PAGE 118,121
TITLE TEST1 ---- 06/10/85 POWER ON SELF TEST (POST)
.286C

;-------------------------------------------------------------------------------
; BIOS I/O INTERFACE							       ;
;									       ;
;	THESE LISTINGS PROVIDE INTERFACE INFORMATION FOR ACCESSING	       ;
;	THE BIOS ROUTINES.  THE POWER ON SELF TEST IS INCLUDED. 	       ;
;									       ;
;	THE  BIOS  ROUTINES  ARE  MEANT  TO  BE  ACCESSED  THROUGH	       ;
;	SOFTWARE  INTERRUPTS  ONLY.    ANY  ADDRESSES  PRESENT	IN	       ;
;	THESE  LISTINGS  ARE  INCLUDED	 ONLY	FOR  COMPLETENESS,	       ;
;	NOT  FOR  REFERENCE.   APPLICATIONS  WHICH  REFERENCE  ANY	       ;
;	ABSOLUTE  ADDRESSES  WITHIN  THE  CODE	SEGMENTS  OF  BIOS	       ;
;	VIOLATE  THE  STRUCTURE  AND  DESIGN  OF  BIOS. 		       ;
;									       ;
;-------------------------------------------------------------------------------



;-------------------------------------------------------------------------------
;   MODULE REFERENCE							       ;
;									       ;
;    TEST1.ASM	    -->  POST AND MANUFACTURING TEST ROUTINES		       ;
;      DSEG.INC     -->   DATA SEGMENTS LOCATIONS			       ;
;      POSTEQU.INC  -->   COMMON EQUATES FOR POST AND BIOS		       ;
;      SYSDATA.INC  -->   POWER ON SELF TEST EQUATES FOR PROTECTED MODE        ;
;			   POST TEST.01 THROUGH TEST.16 		       ;
;    TEST2.ASM	    -->  POST TEST AND INITIALIZATION ROUTINES		       ;
;			   POST TEST.17 THROUGH TEST.22 		       ;
;    TEST3.ASM	    -->  POST EXCEPTION INTERRUPT TESTS 		       ;
;    TEST4.ASM	    -->  POST AND BIOS UTILITY ROUTINES 		       ;
;			   CMOS_READ	 - READ CMOS LOCATION ROUTINE	       ;
;			   CMOS WRITE	 - WRITE CMOS LOCATION ROUTINE	       ;
;			   DDS		 - LOAD (DS:) WITH DATA SEGMENT        ;
;			   E_MSG	 - POST ERROR MESSAGE HANDLER	       ;
;			   MFG_HALT	 - MANUFACTURING ERROR TRAP	       ;
;			   P_MSG	 - POST STRING DISPLAY ROUTINE	       ;
;			   ERR_BEEP	 - POST ERROR BEEP PROCEDURE	       ;
;			   BEEP 	 - SPEAKER BEEP CONTROL ROUTINE        ;
;			   WAITF	 - FIXED TIME WAIT ROUTINE	       ;
;			   CONFIG_BAD	 - SET BAD CONFIG IN CMOS_DIAG	       ;
;			   XPC_BYTE	 - DISPLAY HEX BYTE AS 00 - FF	       ;
;			   PRT_HEX	 - DISPLAY CHARACTER		       ;
;			   PRT_SEG	 - DISPLAY SEGMENT FORMAT ADDRESS      ;
;			   PROT_PRT_HEX  - POST PROTECTED MODE DISPLAY	       ;
;			   ROM_CHECKSUM  - CHECK ROM MODULES FOR CHECKSUM      ;
;			   ROM_CHECK	 - ROM SCAN AND INITIALIZE	       ;
;			   KBD_RESET	 - POST KEYBOARD RESET ROUTINE	       ;
;			   BLINK_INT	 - MANUFACTURING TOGGLE BIT ROUTINE    ;
;			   SET_TOD	 - SET TIMER FROM CMOS RTC	       ;
;			   D11		 - DUMMY INTERRUPT HANDLER   ->INT ??H ;
;			   RE_DIRECT	 - HARDWARE INT  9 REDIRECT (L 2)      ;
;			   INT_287	 - HARDWARE INT 13 REDIRECT (287)      ;
;			   PROC_SHUTDOWN - 80286 RESET ROUTINE		       ;
;    TEST5.ASM	    -->  EXCEPTTON INTERRUPT TEST HANDLERS FOR POST TESTS      ;
;			   SYSINIT1	 - BUILD PROTECTED MODE POINTERS       ;
;			   GDT_BLD	 - BUILD THE GDT FOR POST	       ;
;			   SIDT_BLD	 - BUILD THE IDT FOR POST	       ;
;    TEST6.ASM	    -->  POST TESTS AND SYSTEM BOOT STRAP		       ;
;			   STGTST_CNT	 - SEGMENT STORAGE TEST 	       ;
;			   ROM_ERR	 - ROM ERROR DISPLAY ROUTINE	       ;
;			   XMIT_8042	 - KEYBOARD DIAGNOSTIC OUTPUT	       ;
;			   BOOT_STRAP	 - BOOT STRAP LOADER	      -INT 19H ;
;									       ;
;    DSKETTE.ASM    -->  DISKETTE BIOS					       ;
;			   DISKETTE_IO_1 - INT 13H BIOS ENTRY (40H)   -INT 13H ;
;			   DISK_INT_1	 - HARDWARE INTERRUPT HANDLER -INT 0EH ;
;			   DSKETTE_SETUP - POST SETUP DRIVE TYPES	       ;
;    DISK.ASM	    -->  FIXED DISK BIOS				       ;
;			   DISK_SETUP	 - SETUP DISK VECTORS AND TEST	       ;
;			   DISK_IO	 - INT 13H BIOS ENTRY	      -INT 13H ;
;			   HD_INT	 - HARDWARE INTERRUPT HANDLER -INT 76H ;
;    KYBD.ASM	    -->  KEYBOARD BIOS					       ;
;			   KEYBOARD_IO_1 - INT 16H BIOS ENTRY	      -INT 16H ;
;			   KB_INT_1	 - HARDWARE INTERRUPT	      -INT 09H ;
;			   SND_DATA	 - KEYBOARD TRANSMISSION	       ;
;    PRT.ASM	    -->  PRINTER ADAPTER BIOS			      -INT 17H ;
;    RS232.ASM	    -->  COMMUNICATIONS BIOS FOR RS232		      -INT 14H ;
;    VIDEO1.ASM     -->  VIDEO BIOS				      -INT 10H ;
;    BIOS.ASM	    -->  BIOS ROUTINES					       ;
;			   MEMORY_SIZE_DET_1 - REAL MODE SIZE	      -INT 12H ;
;			   EQUIPMENT_1	 - EQUIPMENT DETERMINATION    -INT 11H ;
;			   NMI_INT_1	 - NMI HANDLER		      -INT 02H ;
;    BIOS1.ASM	    -->  INTERRUPT 15H BIOS ROUTINES		      -INT 15H ;
;			   DEV_OPEN	 - NULL DEVICE OPEN HANDLER	       ;
;			   DEV_CLOSE	 - NULL DEVICE CLOSE HANDLER	       ;
;			   PROG_TERM	 - NULL PROGRAM TERMINATION	       ;
;			   EVENT_WAIT	 - RTC EVENT WAIT/TIMEOUT ROUTINE      ;
;			   JOY_STICK	 - JOYSTICK PORT HANDLER	       ;
;			   SYS_REQ	 - NULL SYSTEM REQUEST KEY	       ;
;			   WAIT 	 - RTC TIMED WAIT ROUTINE	       ;
;			   BLOCKMOVE	 - EXTENDED MEMORY MOVE INTERFACE      ;
;			   GATE_A20	 - ADDRESS BIT 20 CONTROL	       ;
;			   EXT_MEMORY	 - EXTENDED MEMORY SIZE DETERMINE      ;
;			   SET_VMODE	 - SWITCH PROCESSOR TO VIRTUAL MODE    ;
;			   DEVICE_BUSY	 - NULL DEVICE BUSY HANDLER	       ;
;			   INT_COMPLETE  - NULL INTERRUPT COMPLETE HANDLER     ;
;    BIOS2.ASM	    -->  BIOS INTERRUPT ROUTINES			       ;
;			   TIME_OF_DAY_1 - TIME OF DAY ROUTINES       -INT 1AH ;
;			   RTC_INT	 - IRQ LEVEL 8 ALARM HANDLER  -INT 70H ;
;			   PRINT_SCREEN1 - PRINT SCREEN ROUTINE       -INT 05H ;
;			   TIMER_INT_1	 - TIMER1 INTERRUPT HANDLER  ->INT 1CH ;
;    ORGS.ASM	    -->  COMPATIBILITY MODULE				       ;
;			   POST ERROR MESSAGES				       ;
;			   DISKETTE - DISK - VIDEO DATA TABLES		       ;
;-------------------------------------------------------------------------------
.XLIST
INCLUDE IAPX286.INC
SUBTTL DSEG.INC - DATA SEGMENTS
.LIST
PAGE
INCLUDE DSEG.INC
.XLIST
SUBTTL POSTEQU.INC - COMMON EQUATES
.LIST
PAGE
INCLUDE POSTEQU.INC
.XLIST
SUBTTL SYSDATA.INC - DESCRIPTOR EQUATES
.LIST
PAGE
INCLUDE SYSDATA.INC
.XLIST
SUBTTL
.LIST
PAGE
CODE	SEGMENT WORD PUBLIC

	PUBLIC	C8042
	PUBLIC	OBF_42
	PUBLIC	POST1
	PUBLIC	START_1

	EXTRN	CMOS_READ:NEAR
	EXTRN	CMOS_WRITE:NEAR
	EXTRN	CONFIG_BAD:NEAR
	EXTRN	D11:NEAR
	EXTRN	DDS:NEAR
	EXTRN	DUMMY_RETURN:NEAR
	EXTRN	ERR_BEEP:NEAR
	EXTRN	GATE_A20:NEAR
	EXTRN	KBD_RESET:NEAR
	EXTRN	NMI_INT:NEAR
	EXTRN	POST2:NEAR
	EXTRN	PRINT_SCREEN:NEAR
	EXTRN	PROC_SHUTDOWN:NEAR
	EXTRN	ROM_CHECK:NEAR
	EXTRN	SHUT2:NEAR
	EXTRN	SHUT3:NEAR
	EXTRN	SHUT4:NEAR
	EXTRN	SHUT6:NEAR
	EXTRN	SHUT7:NEAR
	EXTRN	SHUT9:NEAR
	EXTRN	SLAVE_VECTOR_TABLE:NEAR
	EXTRN	STGTST_CNT:NEAR
	EXTRN	SYSINIT1:NEAR
	EXTRN	VECTOR_TABLE:NEAR
	EXTRN	VIDEO_PARMS:BYTE

	ASSUME	CS:CODE,DS:NOTHING,ES:NOTHING,SS:NOTHING

POST1	PROC	NEAR

BEGIN	EQU	$
	DB	'6480090COPR. IBM CORP. 1981,1985  '           ;COPYRIGHT NOTICE
	EVEN						       ;EVEN BOUNDARY
	;	 6 4 8 0 0 9 0	 C O P R .   I B M   1 9 8 5   ;EVEN MODULE
	;	  6 4 8 0 0 9 1   C O P R .   I B M   1 9 8 5  ;ODD  MODULE
	DB	'66448800009901  CCOOPPRR..  IIBBMM  11998855' ;COPYRIGHT NOTICE
	DB	'  '                                           ;PAD

;------------------------------------------------
;	INITIAL RELIABILITY TESTS -- (POST1)	:
;------------------------------------------------

;----------------------------------------
; TEST.01				:
;      80286 PROCESSOR TEST (REAL MODE) :
; DESCRIPTION				:
;      VERIFY FLAGS, REGISTERS		:
;      AND CONDITIONAL JUMPS.		:
;----------------------------------------

	ASSUME	DS:DATA

START_1:
	CLI				; DISABLE INTERRUPTS
	MOV	AX,0D500H+CMOS_REG_D+NMI; FLAG MASK IN (AH) AND NMI MASK IN (AL)
	OUT	CMOS_PORT,AL		; DISABLE NMI INTERRUPTS
	SAHF				; SET "SF" "ZF" "AF" "PF" "CF" FLAGS ON
	JNC	ERR02			; GO TO ERROR ROUTINE IF "CF" NOT SET
	JNZ	ERR02			; GO TO ERROR ROUTINE IF "ZF" NOT SET
	JNP	ERR02			; GO TO ERROR ROUTINE IF "PF" NOT SET
	JNS	ERR02			; GO TO ERROR ROUTINE IF "SF" NOT SET
	LAHF				; LOAD FLAG IMAGE TO (AH)
	MOV	CL,5			; LOAD COUNT REGISTER WITH SHIFT COUNT
	SHR	AH,CL			; SHIFT "AF" INTO CARRY BIT POSITION
	JNC	ERR02			; GO TO ERROR ROUTINE IF "AF" NOT SET
	MOV	AL,40H			; SET THE "OF" FLAG ON
	SHL	AL,1			; SETUP FOR TESTING
	JNO	ERR02			; GO TO ERROR ROUTINE IF "OF" NOT SET
	XOR	AH,AH			; SET (AH) = 0
	SAHF				; CLEAR "SF", "CF", "ZF", AND "PF"
	JBE	ERR02			; GO TO ERROR ROUTINE IF "CF" ON
					; GO TO ERROR ROUTINE IF "ZF" ON
	JS	ERR02			; GO TO ERROR ROUTINE IF "SF" ON
	JP	ERR02			; GO TO ERROR ROUTINE IF "PF" ON
	LAHF				; LOAD FLAG IMAGE TO (AH)
	SHR	AH,CL			; SHIFT "AF" INTO CARRY BIT POSITION
	JC	ERR02			; GO TO ERROR ROUTINE IF ON
	SHL	AH,1			; CHECK THAT "OF" IS CLEAR
	JO	ERR02			; GO TO ERROR ROUTINE IF ON
	JZ	C7A			; CONTINUE CONFIDENCE TESTS IF "ZF" SET
ERR02:
	HLT				;	ERROR HALT
	JMP	ERR02			; ERROR LOOP TRAP
C7A:
	MOV	AX,DATA 		; SET DATA SEGMENT
	MOV	DS,AX			; INTO THE (DS) SEGMENT REGISTER

;-----	CHECK FOR PROCESSOR SHUTDOWN

	IN	AL,STATUS_PORT		; READ CURRENT KEYBOARD PROCESSOR STATUS
	TEST	AL,SYS_FLAG		; CHECK FOR SHUTDOWN IN PROCESS FLAG
	JNZ	C7B			; GO IF YES
	JMP	SHUT0			; USE CONTINUE NORMAL POWER ON CODE
PAGE
;-----	CHECK FOR SHUTDOWN 09
C7B:
	MOV	AL,CMOS_SHUT_DOWN+NMI	; CMOS ADDRESS FOR SHUTDOWN BYTE
	OUT	CMOS_PORT,AL
	JMP	$+2			; I/O DELAY
	IN	AL,CMOS_DATA		; GET REQUEST NUMBER
	CMP	AL,09H			; WAS IT SHUTDOWN REQUEST 9?
	XCHG	AL,AH			; SAVE THE SHUTDOWN REQUEST
	JE	C7C			; BYPASS INITIALIZING INTERRUPT CHIPS

;-----	CHECK FOR SHUTDOWN 0A

	CMP	AH,0AH			; WAS IT SHUTDOWN REQUEST A?
	JE	C7C			; BYPASS INITIALIZING INTERRUPT CHIPS

	SUB	AL,AL			; INSURE MATH PROCESSOR RESET
	OUT	X287+1,AL

;--------------------------------------------------------
;    RE-INITIALIZE THE 8259 INTERRUPT #1 CONTROLLER CHIP :
;--------------------------------------------------------
	MOV	AL,11H			; ICW1 - EDGE, MASTER, ICW4
	OUT	INTA00,AL
	JMP	$+2			; WAIT STATE FOR I/O
	MOV	AL,08H			; SETUP ICW2 - INTERRUPT TYPE 8H (8-F)
	OUT	INTA01,AL
	JMP	$+2			; WAIT STATE FOR I/O
	MOV	AL,04H			; SETUP ICW3 - MASTER LEVEL 2
	OUT	INTA01,AL
	JMP	$+2			; I/O WAIT STATE
	MOV	AL,01H			; SETUP ICW4 - MASTER,8086 MODE
	OUT	INTA01,AL
	JMP	$+2			; WAIT STATE FOR I/O
	MOV	AL,0FFH 		; MASK ALL INTERRUPTS OFF
	OUT	INTA01,AL		; (VIDEO ROUTINE ENABLES INTERRUPTS)
;---------------------------------------------------------
;    RE-INITIALIZE THE 8259 INTERRUPT #2 CONTROLLER CHIP  :
;---------------------------------------------------------
	MOV	AL,11H			; ICW1 - EDGE, SLAVE ICW4
	OUT	INTB00,AL
	JMP	$+2			; WAIT STATE FOR I/O
	MOV	AL,INT_TYPE		; SETUP ICW2 - INTERRUPT TYPE 70 (70-7F)
	OUT	INTB01,AL
	MOV	AL,02H			; SETUP ICW3 - SLAVE LEVEL 2
	JMP	$+2
	OUT	INTB01,AL
	JMP	$+2			; I/O DELAY
	MOV	AL,01H			; SETUP ICW4 - 8086 MODE, SLAVE
	OUT	INTB01,AL
	JMP	$+2			; WAIT STATE FOR I/O
	MOV	AL,0FFH 		; MASK ALL INTERRUPTS OFF
	OUT	INTB01,AL
;-------------------------------------------------------------------------------
;  SHUTDOWN - RESTART							       :
;	RETURN CONTROL AFTER A SHUTDOWN COMMAND IS ISSUED		       :
;  DESCRIPTION								       :
;	A TEST IS MADE FOR THE SYSTEM FLAG BEING SET.  IF THE SYSTEM FLAG IS   :
;	SET, THE SHUTDOWN BYTE IN CMOS IS USED TO DETERMINE WHERE CONTROL IS   :
;	RETURNED.							       :
;									       :
;	CMOS = 0   SOFT RESET OR UNEXPECTED SHUTDOWN			       :
;	CMOS = 1   SHUT DOWN AFTER MEMORY SIZE				       :
;	CMOS = 2   SHUT DOWN AFTER MEMORY TEST				       :
;	CMOS = 3   SHUT DOWN WITH MEMORY ERROR				       :
;	CMOS = 4   SHUT DOWN WITH BOOT LOADER REQUEST			       :
;	CMOS = 5   JMP DWORD REQUEST - (INTERRUPT CHIPS & 287 ARE INITIALIZED) :
;	CMOS = 6   PROTECTED MODE TEST3 PASSED				       :
;	CMOS = 7   PROTECTED MODE TEST3 FAILED				       :
;	CMOS = 8   PROTECTED MODE TEST1 FAILED				       :
;	CMOS = 9   BLOCK MOVE SHUTDOWN REQUEST				       :
;	CMOS = A   JMP DWORD REQUEST - (W/O INTERRUPT CHIPS INITIALIZED)       :
;									       :
;	   NOTES:  RETURNS ARE MADE WITH INTERRUPTS AND NMI DISABLED.	       :
;		USER MUST RESTORE SS:SP (POST DEFAULT SET = 0000:0400),        :
;		ENABLE NON-MASKABLE INTERRUPTS (NMI) WITH AN OUT TO	       :
;		PORT 70H WITH HIGH ORDER BIT OFF, AND THEN ISSUE A	       :
;		STI TO ENABLE INTERRUPTS. FOR SHUTDOWN (5) THE USER	       :
;		MUST ALSO RESTORE THE INTERRUPT MASK REGISTERS. 	       :
;-------------------------------------------------------------------------------

;-----	CHECK FROM WHERE
C7C:
	MOV	AL,CMOS_SHUT_DOWN+NMI	; CLEAR CMOS BYTE
	OUT	CMOS_PORT,AL
	NOP				; I/O DELAY
	SUB	AL,AL			; SET BYTE TO 0
	OUT	CMOS_DATA,AL
	XCHG	AH,AL
	CMP	AL,0AH			; COMPARE WITH MAXIMUM TABLE ENTRIES
	JA	SHUT0			; SKIP TO POST IF GREATER THAN MAXIMUM
	MOV	SI,OFFSET BRANCH	; POINT TO THE START OF THE BRANCH TABLE
	ADD	SI,AX
	ADD	SI,AX			; POINT TO BRANCH ADDRESS
	MOV	BX,CS:[SI]		; MOVE BRANCH TO ADDRESS TO BX REGISTER

;----- SET TEMPORARY STACK FOR POST

	MOV	AX,ABS0 		; SET STACK SEGMENT TO ABS0 SEGMENT
	MOV	SS,AX
	MOV	SP,OFFSET @TOS		; SET STACK POINTER TO END OF VECTORS
	JMP	BX			; JUMP BACK TO RETURN ROUTINE

BRANCH: DW	SHUT0			; NORMAL POWER UP/UNEXPECTED SHUTDOWN
	DW	SHUT1			; SHUT DOWN AFTER MEMORY SIZE
	DW	SHUT2			; SHUT DOWN AFTER MEMORY TEST
	DW	SHUT3			; SHUT DOWN WITH MEMORY ERROR
	DW	SHUT4			; SHUT DOWN WITH BOOT LOADER REQUEST
	DW	SHUT5			; JMP DWORD REQUEST WITH INTERRUPT INIT
	DW	SHUT6			; PROTECTED MODE TEST7 PASSED
	DW	SHUT7			; PROTECTED MODE TEST7 FAILED
	DW	SHUT8			; PROTECTED MODE TEST1 FAILED
	DW	SHUT9			; BLOCK MOVE SHUTDOWN REQUEST
	DW	SHUTA			; JMP DWORD REQUEST (W/O INTERRUPT INIT)
PAGE
;-----	@IO_ROM_INIT MUST BE INITIALIZED BY THE USER FOR VECTORED REQUESTS

SHUT5:
	IN	AL,PORT_A		; FLUSH THE KEYBOARD BUFFER
	MOV	AL,EOI			; FLUSH LAST TIMER REQUEST IF PENDING
	OUT	INTA00,AL		;  - TO ALLOW TIMER INTERRUPTS
SHUTA:
	JMP	DWORD PTR @IO_ROM_INIT	; FAR JUMP TO USER DEFINED LOCATION
					;  AFTER SHUTDOWN TO REAL MODE CODE
					;  WITH INTERRUPTS AND NMI DISABLED
;-----	CHECKPOINT 01

SHUT0:
	MOV	AL,01H			;	<><><><><><><><><><><><>
	OUT	MFG_PORT,AL		;	<><> CHECKPOINT  01 <><>

;-----	READ/WRITE/TEST THE 80286 REGISTERS WITH ONE'S AND ZERO'S

	MOV	AX,0FFFFH		; SETUP ONE'S PATTERN IN (AX)
	STC				; SET CARRY FLAG
	JNC	ERR01			; GO IF NO CARRY
C8:
	MOV	DS,AX			; WRITE PATTERN TO ALL REGISTERS
	MOV	BX,DS
	MOV	ES,BX
	MOV	CX,ES
	MOV	SS,CX
	MOV	DX,SS
	MOV	SP,DX
	MOV	BP,SP
	MOV	SI,BP
	MOV	DI,SI
	JNC	C9
	XOR	AX,DI			; PATTERN MAKE IT THROUGH ALL REGISTERS
	JNZ	ERR01			; NO - GO TO ERROR ROUTINE
	CLC				; CLEAR CARRY FLAG
	JMP	C8
C9:					; TST1A
	OR	AX,DI			; ZERO PATTERN MAKE IT THROUGH ?
	JZ	C10A			; YES - GO TO NEXT TEST
ERR01:
	HLT				; HALT SYSTEM

;-----	INSURE THAT CMOS CLOCK INTERRUPTS ARE DISABLED
C10A:
	MOV	AX,X*(CMOS_REG_B+NMI)	; ADDRESS TO BOTH (AH) AND (AL)
	OUT	CMOS_PORT,AL		; ADDRESS CMOS ALARM BYTE WITH NMI=OFF
	NOP				; I/O DELAY
	IN	AL,CMOS_DATA		; GET THE CURRENT CONTROL REGISTER
	AND	AL,00000111B		; CLEAR SET,PIE,AIE, AND SQWE BITS
	XCHG	AL,AH			; SAVE IT
	OUT	CMOS_PORT,AL
	XCHG	AL,AH
	OUT	CMOS_DATA,AL

	MOV	AL,CMOS_REG_C+NMI	; ADDRESS CMOS FLAGS BYTE WITH NMI=OFF
	NOP				; I/O DELAY
	OUT	CMOS_PORT,AL
	NOP				; I/O DELAY
	IN	AL,CMOS_DATA		; READ STATUS TO CLEAR PENDING INTERRUPT

;----- RESET VIDEO

	MOV	AL,0			; CLEAR DATA BYTE TO DISABLE VIDEO
	MOV	DX,03D8H		; GET COLOR MODE CONTROL PORT ADDRESS
	OUT	DX,AL			; DISABLE COLOR VIDEO
	INC	AL			; MONOCHROME MODE RESET MASK
	MOV	DL,0B8H 		; GET ADDRESS OF MONOCHROME MODE CONTROL
	OUT	DX,AL			; DISABLE B/W VIDEO, ENABLE HIGH RES
	MOV	DL,0BAH 		; ADDRESS OF MONOCHROME STATUS REGISTER
	IN	AL,DX			; READ STATUS TO DISABLE EGA VIDEO
	MOV	DL,0DAH 		; ADDRESS OF COLOR MODE STATUS REGISTER
	IN	AL,DX			; READ STATUS TO DISABLE EGA VIDEO
	MOV	AL,0			; SELECT ATTRIBUTE PALETTE REGISTER 0
	MOV	DL,0C0H 		; WRITE 0 TO ATTRIBUTE ADDRESS REGISTER
	OUT	DX,AL			; TO DISABLE EGA VIDEO
	MOV	AL,11111100B		; DISABLE PARITY CHECKERS
	OUT	PORT_B,AL

;----------------------------------------
; TEST.02				:
;	ROM CHECKSUM TEST 1		:
; DESCRIPTION				:
;	A CHECKSUM IS DONE FOR THE 32K	:
;	READ ONLY MEMORY MODULES (TWO)	:
;	CONTAINING POST, BASIC AND BIOS.:
;----------------------------------------

;-----	CHECKPOINT 02

	MOV	AL,02H			;	<><><><><><><><><><><><>
	OUT	MFG_PORT,AL		;	<><> CHECKPOINT  02 <><>

	ASSUME	SS:CODE
	MOV	AX,CS			; SETUP SS SEGMENT REGISTER
	MOV	SS,AX
	MOV	DS,AX			; SET UP DATA SEGMENT TO POINT TO
	XOR	SI,SI			; ROM ADDRESS START
	XOR	BX,BX			; CLEAR CHECK REGISTER
	MOV	CH,080H 		; COUNT FOR 32K WORDS
C11:
	LODSW				; MOVE TWO BYTES INTO AX -- SI=SI+2
	ADD	BL,AH			; ADD ODD BYTE AT DS:SI+1 TO CHECKSUM
	ADD	BL,AL			; ADD EVEN BYTE AT DS:SI TO CHECKSUM
	LOOP	C11			; LOOP COUNT FOR 65K BYTES (32K WORDS)
	JNC	C11E			;  EXIT IF "LOOP" RESET THE CARRY FLAG
					;  (NOTE: MODEL BYTE MUST NOT = ZERO)
	JZ	C11A			; CONTINUE IF CHECKSUM VALID (ZERO)
C11E:
	HLT				; ELSE HALT IF CHECKSUM PROBLEM
;----------------------------------------
; TEST.03				:
;	VERIFY CMOS SHUTDOWN BYTE	:
; DESCRIPTION				:
;	ROLLING BIT WRITTEN AND 	:
;	VERIFIED AT SHUTDOWN ADDRESS.	:
;----------------------------------------

;-----	VERIFY AND CLEAR SHUTDOWN FLAG
C11A:
	MOV	AL,03H			;	<><><><><><><><><><><><>
	OUT	MFG_PORT,AL		;	<><> CHECKPOINT  03 <><>

	MOV	CX,09H			; LOOP COUNT
	MOV	AH,1			; START WITH BIT 0
C11B:
	MOV	AL,CMOS_SHUT_DOWN+NMI
	OUT	CMOS_PORT,AL
	MOV	AL,AH			; OUTPUT ROLLING BIT
	OUT	CMOS_DATA,AL
	MOV	AL,CMOS_SHUT_DOWN+NMI	; READ CMOS
	NOP				; I/O DELAY
	OUT	CMOS_PORT,AL
	NOP				; I/O DELAY
	IN	AL,CMOS_DATA
	CMP	AL,AH			; MUST BE THE SAME
	JNZ	ERR01			; ERROR IF NOT
	RCL	AH,1			; ROLL A BIT THROUGH SHUTDOWN BYTE
	LOOP	C11B			; LOOP TILL DONE

;----------------------------------------
; TEST.04				:
;	8254 CHECK TIMER 1 ALL BITS ON	:
; DESCRIPTION				:
;	SET TIMER COUNT 		:
;	CHECK THAT TIMER 1 ALL BITS ON	:
;----------------------------------------
	ASSUME	DS:DATA
	MOV	AX,DATA 		; SET DATA SEGMENT
	MOV	DS,AX
	MOV	AL,04H			;	<><><><><><><><><><><><>
	OUT	MFG_PORT,AL		;	<><> CHECKPOINT  04 <><>

;-----	DISABLE DMA CONTROLLER
					; (AL) ALREADY = 04H
	OUT	DMA08,AL		; DISABLE DMA CONTROLLER 1
	OUT	DMA18,AL		; DISABLE DMA CONTROLLER 2

;-----	VERIFY THAT TIMER 1 FUNCTIONS OK

	MOV	DX,@RESET_FLAG		; SAVE RESET FLAG WHILE REFRESH IS OFF
	MOV	AL,54H			; SELECT TIMER 1,LSB,MODE 2
	OUT	TIMER+3,AL
	JMP	$+2			; I/O DELAY
	MOV	AL,CL			; SET INITIAL TIMER COUNT TO 0
	OUT	TIMER+1,AL
	MOV	BH,05H			; LOOP COUNT
C12:					; TIMER1_BITS_ON
	MOV	AL,40H			; LATCH TIMER 1 COUNT
	JMP	$+2			; I/O DELAY
	OUT	TIMER+3,AL
	CMP	BL,0FFH 		; YES - SEE IF ALL BITS GO OFF
	JE	C13			; TIMER1_BITS_OFF
	IN	AL,TIMER+1		; READ TIMER 1 COUNT
	OR	BL,AL			; ALL BITS ON IN TIMER
	LOOP	C12			; TIMER1_BITS_ON
	DEC	BH
	JNZ	C12			; TRY AGAIN
	HLT				; TIMER 1 FAILURE, HALT SYSTEM
					; TIMER1_BITS_OFF
;----------------------------------------
; TEST.05				:
;	8254 CHECK TIMER 1 ALL BIT OFF	:
; DESCRIPTION				:
;	SET TIMER COUNT 		:
;	CHECK THAT TIMER 1 ALL BITS OFF :
;----------------------------------------

;-----	CHECKPOINT 05

C13:	MOV	AL,05H			;	<><><><><><><><><><><><>
	OUT	MFG_PORT,AL		;	<><>  CHECKPOINT 05 <><>

	MOV	AL,BL			; SET TIMER 1 COUNT
	SUB	CX,CX
	OUT	TIMER+1,AL
	MOV	BH,05H			; SET TRY AGAIN COUNT
C14:					; TIMER_LOOP
	MOV	AL,40H			; LATCH TIMER 1 COUNT
	OUT	TIMER+3,AL
	JMP	$+2			; DELAY FOR TIMER
	JMP	$+2			; ADDED DELAY FOR TIMER
	IN	AL,TIMER+1		; READ TIMER 1 COUNT
	AND	BL,AL
	JZ	C15			; GO TO WRAP DMA REGISTER TESTS
	LOOP	C14			; TIMER_LOOP
	DEC	BH
	JNZ	C14
	HLT				; HALT SYSTEM

;----------------------------------------
; TEST.06				:
;	8237 DMA 0 INITIALIZATION	:
;	CHANNEL REGISTER TEST		:
; DESCRIPTION				:
;	DISABLE THE 8237 DMA CONTROLLER.:
;	WRITE/READ THE CURRENT ADDRESS	:
;	AND WORD COUNT REGISTERS FOR	:
;	ALL CHANNELS.			:
;----------------------------------------

;-----	CHECKPOINT 06

C15:
	MOV	AX,DATA 		; SET DATA SEGMENT
	MOV	DS,AX
	MOV	AL,06H			;	<><><><><><><><><><><><>
	OUT	MFG_PORT,AL		;	<><> CHECKPOINT  06 <><>
	MOV	@RESET_FLAG,DX		; RESTORE SOFT RESET FLAG
	OUT	DMA+0DH,AL		; SEND MASTER CLEAR TO DMA

;-----	WRAP DMA 0 CHANNEL ADDRESS AND COUNT REGISTERS

	MOV	AL,0FFH 		; WRITE PATTERN "FF" TO ALL REGISTERS
C16:	MOV	BL,AL			; SAVE PATTERN FOR COMPARE
	MOV	BH,AL
	MOV	CX,8			; SETUP LOOP COUNT
	MOV	DX,DMA			; SETUP I/O PORT ADDRESS OF REGISTER
C17:	OUT	DX,AL			; WRITE PATTERN TO REGISTER, LSB
	JMP	$+2			; I/O DELAY
	OUT	DX,AL			; MSB OF 16 BIT REGISTER
	MOV	AL,01H			; AL TO ANOTHER PATTERN BEFORE READ
	JMP	$+2			; I/O DELAY
	IN	AL,DX			; READ 16-BIT DMA CH REG, LSB 2ST DMA
	JMP	$+2			; I/O DELAY
	MOV	AH,AL			; SAVE LSB OF 16-BIT REGISTER
	IN	AL,DX			; READ MSB OF DMA CHANNEL REGISTER
	CMP	BX,AX			; PATTERN READ AS WRITTEN?
	JE	C18			; YES	- CHECK NEXT REGISTER
	HLT				; NO - HALT THE SYSTEM
C18:					; NXT_DMA_CH
	INC	DX			; SET I/O PORT TO NEXT CHANNEL REGISTER
	LOOP	C17			; WRITE PATTERN TO NEXT REGISTER
	INC	AL			; SET PATTERN TO 0
	JZ	C16			; YES CONTINUE

;-----	WRITE DMA WITH 55 PATTERN

	CMP	BL,055H 		; CHECK IF "55" PATTERN DONE
	JZ	C19			; GO IF YES
	CMP	BL,0AAH 		; CHECK IF "AA" PATTERN DONE
	JZ	C20			; GO IF YES
	MOV	AL,055H
	JMP	C16

;-----	WRITE DMA WITH AA PATTERN

C19:	MOV	AL,0AAH
	JMP	C16

;----------------------------------------
; TEST.07				:
;	8237 DMA 1 INITIALIZATION	:
;	CHANNEL REGISTER TEST		:
; DESCRIPTION				:
;	DISABLE 8237 DMA CONTROLLER 1.	:
;	WRITE/READ THE CURRENT DMA 1	:
;	ADDRESS AND WORD COUNT		:
;	REGISTERS FOR ALL CHANNELS.	:
;----------------------------------------

;-----	CHECKPOINT 07 - DMA 1

C20:	MOV	AL,07H			;	<><><><><><><><><><><><>
	OUT	MFG_PORT,AL		;	<><> CHECKPOINT  07 <><>
	OUT	DMA1+0DH*2,AL		; SEND MASTER CLEAR TO 2ND DMA

;-----	WRAP DMA 1 CHANNEL ADDRESS AND COUNT REGISTERS

	MOV	AL,0FFH 		; WRITE PATTERN FF TO ALL REGISTERS
C16A:	MOV	BL,AL			; SAVE PATTERN FOR COMPARE
	MOV	BH,AL
	MOV	CX,8			; SETUP LOOP COUNT
	MOV	DX,DMA1 		; SETUP I/O PORT ADDRESS OF REGISTER
C17A:	OUT	DX,AL			; WRITE PATTERN TO REGISTER, LSB
	JMP	$+2			; I/O DELAY
	OUT	DX,AL			; MSB OF 16 BIT REGISTER
	MOV	AL,01H			; AL TO ANOTHER PAT BEFORE RD
	JMP	$+2			; I/O DELAY
	IN	AL,DX			; READ 16-BIT DMA CH REG, LSB 2ST DMA
	JMP	$+2			; I/O DELAY
	MOV	AH,AL			; SAVE LSB OF 16-BIT REGISTER
	IN	AL,DX			; READ MSB OF DMA CH REGISTER
	CMP	BX,AX			; PATTERN READ AS WRITTEN?
	JE	C18A			; YES - CHECK NEXT REGISTER
	HLT				; NO - HALT THE SYSTEM
C18A:					; NXT DMA CH
	ADD	DX,2			; SET I/O PORT TO NEXT CHANNEL REGISTER
	LOOP	C17A			; WRITE PATTERN TO NEXT REGISTER
	INC	AL			; SET PATTERN TO 0
	JZ	C16A			; YES CONTINUE

;-----	WRITE DMA WITH 55 PATTERN

	CMP	BL,55H			; CHECK IF 55 PATTERN DONE
	JZ	C20A			; GO IF YES
	CMP	BL,0AAH 		; CHECK IF AA PATTERN DONE
	JZ	C21			; GO IF YES
	MOV	AL,55H
	JMP	C16A

;-----	WRITE DMA WITH AA PATTERN

C20A:	MOV	AL,0AAH
	JMP	C16A

;-----	INITIALIZE AND START MEMORY REFRESH

C21:
	MOV	BX,@RESET_FLAG		; GET THE RESET FLAG
	MOV	@EQUIP_FLAG,AX		; DO A DUMMY MEMORY WRITE BEFORE REFRESH
	MOV	AL,18			; START REFRESH TIMER
	OUT	TIMER+1,AL

;-----	SET DMA COMMAND

	SUB	AL,AL			; DACK SENSE LOW,DREQ SENSE HIGH
	OUT	DMA+8,AL		; LATE WRITE, FIXED PRIORITY, NORMAL
					; TIMING, CONTROLLER ENABLE, CH0 ADDRESS
					; HOLD DISABLE, MEMORY TO MEMORY DISABLE
	OUT	DMA18,AL		; SAME TO SECOND CONTROLLER

;-----	MODE SET ALL DMA CHANNELS

	MOV	AL,40H			; SET MODE FOR CHANNEL 0
	OUT	DMA+0BH,AL
	MOV	AL,0C0H 		; SET CASCADE MODE ON CHANNEL 4
	OUT	DMA18+06H,AL
	JMP	$+2			; I/O DELAY
	MOV	AL,41H			; SET MODE FOR CHANNEL 1
	OUT	DMA+0BH,AL
	OUT	DMA18+06H,AL		; SET MODE FOR CHANNEL 5
	JMP	$+2			; I/O DELAY
	MOV	AL,42H			; SET MODE FOR CHANNEL 2
	OUT	DMA+0BH,AL
	OUT	DMA18+06H,AL		; SET MODE FOR CHANNEL 6
	JMP	$+2			; I/O DELAY
	MOV	AL,43H			; SET MODE FOR CHANNEL 3
	OUT	DMA+0BH,AL
	OUT	DMA18+06H,AL		; SET MODE FOR CHANNEL 7

;-----	RESTORE RESET FLAG

	MOV	@RESET_FLAG,BX

;----------------------------------------
; TEST.08				:
;	DMA PAGE REGISTER TEST		:
; DESCRIPTION				:
;	WRITE/READ ALL PAGE REGISTERS	:
;----------------------------------------

;-----	CHECKPOINT 08

	MOV	AL,08H			;	<><><><><><><><><><><><>
	OUT	MFG_PORT,AL		;	<><> CHECKPOINT  08 <><>
	SUB	AL,AL
	MOV	DX,DMA_PAGE
	MOV	CX,0FFH 		; DO ALL DATA PATTERNS
C22A:	OUT	DX,AL
	INC	DX
	INC	AL
	CMP	DX,8FH			; TEST DMA PAGES 81 THROUGH 8EH
	JNZ	C22A
	XCHG	AH,AL			; SAVE CURRENT DATA PATTERN
	DEC	AH			; CHECK LAST WRITTEN
	DEC	DX
C22B:	SUB	AL,AL			; CHANGE DATA BEFORE READ
	IN	AL,DX
	CMP	AL,AH			; DATA AS WRITTEN?
	JNZ	C26			; GO ERROR HALT IF NOT
	DEC	AH
	DEC	DX
	CMP	DX,MFG_PORT		; CONTINUE TILL PORT 80
	JNZ	C22B
	INC	AH			; NEXT PATTERN TO RIPPLE
	MOV	AL,AH
	LOOP	C22A

;-----	TEST LAST DMA PAGE REGISTER (USED FOR ADDRESS LINES DURING REFRESH)

	MOV	AL,0CCH 		; WRITE AN CC TO PAGE REGISTERS
C22:	MOV	DX,LAST_DMA_PAGE
	MOV	AH,AL			; SAVE THE DATA PATTERN
	OUT	DX,AL			; OUTPUT PAGE REGISTER

;-----	VERIFY PAGE REGISTER 8F

	SUB	AL,AL			; CHANGE DATA PATTERN BEFORE READ
	IN	AL,DX			; GET THE DATA FROM PAGE REGISTER
	CMP	AL,AH
	JNZ	C26			; GO IF ERROR
	CMP	AH,0CCH
	JNZ	C25			; GO IF ERROR
	MOV	AL,033H 		; SET UP DATA PATTERN OF 33
	JMP	C22			; DO DATA 33
C25:
	CMP	AH,0			; CHECK DONE
	JZ	C27			; GO IF YES
	SUB	AL,AL			; SET UP FOR DATA PATTERN 00
	JMP	C22			; DO DATA 0

;-----	ERROR HALT
C26:
	HLT				; HALT SYSTEM

;----------------------------------------
; TEST.09				:
;	STORAGE REFRESH TEST		:
; DESCRIPTION				:
;	VERIFY REFRESH IS OCCURRING	:
;----------------------------------------

;-----	CHECKPOINT 09 - TEST MEMORY REFRESH
C27:
	MOV	AL,09H			;	<><><><><><><><><><><><>
	OUT	MFG_PORT,AL		;	<><> CHECKPOINT  09 <><>
	SUB	CX,CX
C28:
	IN	AL,PORT_B		; INSURE REFRESH BIT IS TOGGLING
	TEST	AL,REFRESH_BIT
	LOOPZ	C28			; INSURE REFRESH IS OFF
	JCXZ	C26			; ERROR HALT IF TIMEOUT
C29:
	IN	AL,PORT_B
	TEST	AL,REFRESH_BIT		; INSURE REFRESH IS ON
	LOOPNZ	C29
	JCXZ	C26			; ERROR HALT IF NO REFRESH BIT

;----------------------------------------
; TEST.10				:
;	8042 INTERFACE TEST		:
;	READ CONFIGURATION JUMPERS	:
; DESCRIPTION				:
;	ISSUE A SELF TEST TO THE 8042.	:
;	INSURE A 55H IS RECEIVED.	:
;	READ MANUFACTURING AND DISPLAY	:
;	JUMPERS AND SAVE IN MFG_TEST.	:
;----------------------------------------

;-----	CHECKPOINT 0A

	MOV	AL,0AH			;	<><><><><><><><><><><><>
	OUT	MFG_PORT,AL		;	<><> CHECKPOINT  0A <><>

;-----	SOFT RESET (HANDLE ALL POSSIBLE CONDITIONS)

	SUB	CX,CX			; 100 MILLISECONDS FOR THIS LOOP
TST1:	IN	AL,STATUS_PORT		; CHECK FOR INPUT BUFFER FULL
	MOV	AH,AL
	TEST	AH,OUT_BUF_FULL
	JZ	TST2			; GO IF NOT
	IN	AL,PORT_A		; FLUSH
TST2:	TEST	AH,INPT_BUF_FULL	; IS THE OUTPUT BUFFER ALSO FULL?
	LOOPNZ	TST1			; TRY AGAIN
	JZ	TST4			; CONTINUE IF OK

ERR0:	HLT				; HALT SYSTEM IF BUFFER FULL

;-----	ISSUE A RESET TO THE 8042

TST4:	MOV	AL,0BH			;	<><><><><><><><><><><><>
	OUT	MFG_PORT,AL		;	<><> CHECKPOINT  0B <><>

	MOV	AL,SELF_TEST		; SELF TEST COMMAND
	MOV	SP,OFFSET C8042A	; SET RETURN ADDRESS
	JMP	SHORT C8042
TST4_B: TEST	AL,OUT_BUF_FULL 	; IS THE OUTPUT BUFFER FULL?
	JZ	TST4_A			; GO IF NOT
	IN	AL,PORT_A		; FLUSH
TST4_A: MOV	SP,OFFSET OBF_42A	; SET RETURN ADDRESS
	JMP	SHORT OBF_42		; GO WAIT FOR BUFFER
TST4_C: IN	AL,PORT_A		; GET THE ENDING RESPONSE
	CMP	AL,55H

	MOV	AL,0CH			;	<><><><><><><><><><><><>
	OUT	MFG_PORT,AL		;	<><> CHECKPOINT  0C <><>

	JNZ	ERR0			; GO IF NOT OK

;-----	GET THE SWITCH SETTINGS

	MOV	AL,READ_8042_INPUT	; READ INPUT COMMAND
	MOV	SP,OFFSET C8042C	; SET RETURN ADDRESS
	JMP	SHORT C8042		; ISSUE COMMAND
E30B:	MOV	SP,OFFSET OBF_42B	; SET RETURN ADDRESS
	JMP	SHORT OBF_42		; GO WAIT FOR RESPONSE
E30C:	IN	AL,PORT_A		; GET THE SWITCH
	OUT	DMA_PAGE+1,AL		; SAVE TEMPORARY

;-----	WRITE BYTE 0 OF 8042 MEMORY

	MOV	AL,WRITE_8042_LOC	; WRITE BYTE COMMAND
	MOV	SP,OFFSET C8042B	; SET RETURN ADDRESS
	JMP	SHORT C8042		; ISSUE THE COMMAND
TST4_D: JZ	TST4_D1 		; CONTINUE IF COMMAND ACCEPTED

	MOV	AL,0DH			;	<><><><><><><><><><><><>
	OUT	MFG_PORT,AL		;	<><> CHECKPOINT  0D <><>
	HLT
TST4_D1:
	MOV	AL,5DH			; ENABLE OUTPUT BUFFER FULL INTERRUPT,
	OUT	PORT_A,AL		; DISABLE KEYBOARD, SET SYSTEM FLAG,
	JMP	SHORT E30A		; PC 1 COMPATIBILITY, INHIBIT OVERRIDE

;-----	ISSUE THE COMMAND TO THE 8042

C8042:	CLI				; NO INTERRUPTS ALLOWED
	OUT	STATUS_PORT,AL		; SEND COMMAND IN AL REGISTER

	SUB	CX,CX			; LOOP COUNT
C42_1:	IN	AL,STATUS_PORT		; WAIT FOR THE COMMAND ACCEPTED
	TEST	AL,INPT_BUF_FULL
	LOOPNZ	C42_1
	RET

;-----	WAIT FOR 8042 RESPONSE

OBF_42: SUB	CX,CX
	MOV	BL,6			; 200MS/PER LOOP * 6 =1200 MS +
C42_2:	IN	AL,STATUS_PORT		; CHECK FOR RESPONSE
	TEST	AL,OUT_BUF_FULL
	JNZ	C42_3			; GO IF RESPONSE
	LOOP	C42_2			; TRY AGAIN
	DEC	BL			; DECREMENT LOOP COUNT
	JNZ	C42_2
C42_3:	RET				; RETURN TO CALLER

;----------------------------------------
; TEST.11				:
;	BASE 64K READ/WRITE MEMORY TEST :
; DESCRIPTION				:
;	WRITE/READ/VERIFY DATA PATTERNS :
;	AA,55,FF,01, AND 00 TO 1 ST 64K :
;	OF STORAGE, VERIFY STORAGE	:
;	ADDRESSABILITY. 		:
;----------------------------------------

;-----	FILL MEMORY WITH DATA

E30A:	MOV	AL,0EH			;	<><><><><><><><><><><><>
	OUT	MFG_PORT,AL		;	<><> CHECKPOINT  0E <><>

	MOV	AX,DATA 		; GET THE SYSTEM SEGMENT
	MOV	DS,AX			;  OF DATA
	MOV	BX,@RESET_FLAG		; SAVE @RESET_FLAG IN BX
	CLD				; SET DIRECTION FLAG TO INCREMENT
	MOV	CX,2000H*4		; SET FOR 32K WORDS
	SUB	DI,DI			; FIRST 16K
	SUB	SI,SI
	SUB	AX,AX
	MOV	DS,AX
	MOV	ES,AX
	CMP	BX,1234H		; WARM START?
	JNZ	E30A_0			; GO IF NOT
	JMP	CLR_STG

;-----	GET THE INPUT BUFFER (SWITCH SETTINGS)

E30A_0: MOV	AL,0FH			;	<><><><><><><><><><><><>
	OUT	MFG_PORT,AL		;	<><> CHECKPOINT  0F <><>
	MOV	AL,PARITY_CHECK 	; SET BASE MEMORY PARITY
	OUT	DMA_PAGE+6,AL		; USE AS TEMPORARY SAVE
	MOV	SP,OFFSET C2		; SET RETURN ADDRESS
	JMP	STGTST_CNT
C30:	MOV	BX,AX			; SAVE FAILING BIT PATTERN
	JNZ	C31
	JMP	C33			; STORAGE OK, CONTINUE

;-----	TEMPORARY STACK FOR POST ROUTINES

C2	DW	C30
C8042A	DW	TST4_B
OBF_42A DW	TST4_C
C8042B	DW	TST4_D
C8042C	DW	E30B
OBF_42B DW	E30C

;-------------------------------------------
; BASE 64K STORAGE FAILURE
;   DISPLAY THE CHECKPOINT (MFG CHECKPOINT)
;     AND XOR EXPECTED WITH READ IN MFG_PORT
;   DISPLAY CHECKPOINT IN MFG_PORT+3
;   DISPLAY XOR'D DATA HIGH BYTE MFG_PORT+1
;     LOW BYTE IN MFG_PORT+2
;   A READ/WRITE SCOPE LOOP OF THE FIRST
;   WORD FOR POSSIBLE ADDRESS LINE FAILURES
;-------------------------------------------

C31:
	MOV	AL,BH			; SAVE HIGH BYTE
	OUT	MFG_PORT+1,AL
	MOV	AL,BL			; SAVE LOW BYTE
	OUT	MFG_PORT+2,AL

;-----	CHECK FOR VIDEO ROM

	MOV	CX,0C000H		; START OF I/O ROM
M1:	MOV	DS,CX			; POINT TO SEGMENT
	SUB	BX,BX			; GET THE FIRST 2 LOCATIONS
	MOV	AX,[BX]
	JMP	$+2			; BUS SETTLE
	CMP	AX,0AA55H		; IS THE VIDEO ROM PRESENT?
	POP
	JZ	Z5			; GO IF YES
	ADD	CX,080H 		; POINT TO NEXT 2K BLOCK
	CMP	CX,0C800H		; TOP OF VIDEO ROM AREA YET?
	JL	M1			; TRY AGAIN
	AND	CX,CX			; SET NON ZERO FLAG
Z5:
	JNZ	C32			; GO IF NOT
	JMP	C31_0			; BYPASS ERROR DISPLAY IF VIDEO ROM

;-------------------------------------------------------
; SET VIDEO MODE TO DISPLAY MEMORY ERROR
;	THIS ROUTINE INITIALIZES THE ATTACHMENT TO
;	TO DISPLAY FIRST 64K STORAGE ERRORS.
; BOTH COLOR AND MONOCHROME ATTACHMENTS ARE INITIALIZED.
;-------------------------------------------------------

;-----	INITIALIZE COLOR/MONOCHROME

C32:	MOV	DX,3D8H 		; CONTROL REGISTER ADDRESS OF COLOR CARD
	SUB	AL,AL			; MODE SET
	OUT	DX,AL

	MOV	DX,03B8H		; CONTROL REGISTER ADDRESS OF B/W CARD
	MOV	AL,1			; MODE SET FOR CARD
	OUT	DX,AL			; RESET VIDEO
	SUB	DX,4			; BACK TO BASE REGISTER

M4	EQU	10H

	MOV	BX,OFFSET VIDEO_PARMS+M4*3  ; POINT TO VIDEO PARAMETERS
	ASSUME	DS:CODE
Z_2:	MOV	CX,M4			; COUNT OF MONOCHROME VIDEO PARAMETERS

;-----	BX POINTS TO CORRECT ROW OF INITIALIZATION TABLE

	XOR	AH,AH			; AH IS REGISTER NUMBER DURING LOOP

;-----	LOOP THROUGH TABLE, OUTPUTTING REGISTER ADDRESS, THEN VALUE FROM TABLE

M10:	MOV	AL,AH			; GET 6845 REGISTER NUMBER
	OUT	DX,AL
	INC	DX			; POINT TO DATA PORT
	INC	AH			; NEXT REGISTER VALUE
	MOV	AL,CS:[BX]		; GET TABLE VALUE
	OUT	DX,AL			; OUT TO CHIP
	INC	BX			; NEXT IN TABLE
	DEC	DX			; BACK TO POINTER REGISTER
	LOOP	M10			; DO THE WHOLE TABLE
	MOV	AH,DL			; CHECK IF COLOR CARD DONE
	AND	AH,0F0H 		; STRIP UNWANTED BITS
	CMP	AH,0D0H 		; IS IT THE COLOR CARD?
	JZ	Z_3			; CONTINUE IF COLOR
	MOV	BX,OFFSET VIDEO_PARMS	; POINT TO VIDEO PARAMETERS
	MOV	DX,3D4H 		; COLOR BASE
	JMP	Z_2			; CONTINUE

;-----	FILL REGEN AREA WITH BLANK

Z_3:	XOR	DI,DI			; SET UP POINTER FOR REGEN
	MOV	AX,0B000H		; SET UP ES TO VIDEO REGEN
	MOV	ES,AX

	MOV	CX,2048 		; NUMBER OF WORDS IN MONOCHROME CARD
	MOV	AX,' '+7*H              ; FILL CHARACTER FOR ALPHA - ATTRIBUTE
	REP	STOSW			; FILL THE REGEN BUFFER WITH BLANKS

	XOR	DI,DI			; CLEAR COLOR VIDEO BUFFER MEMORY
	MOV	BX,0B800H		; SET UP ES TO COLOR VIDEO MEMORY
	MOV	ES,BX
	MOV	CX,8192
	REP	STOSW			; FILL WITH BLANKS

;-----	ENABLE VIDEO AND CORRECT PORT SETTING

	MOV	DX,3B8H
	MOV	AL,29H
	OUT	DX,AL			; SET VIDEO ENABLE PORT

;-----	SET UP OVERSCAN REGISTER

	INC	DX			; SET OVERSCAN PORT TO A DEFAULT
	MOV	AL,30H			; VALUE 30H FOR ALL MODES EXCEPT 640X200
	OUT	DX,AL			; OUTPUT THE CORRECT VALUE TO 3D9 PORT

;-----	ENABLE COLOR VIDEO AND CORRECT PORT SETTING
	MOV	DX,3D8H
	MOV	AL,28H
	OUT	DX,AL			; SET VIDEO ENABLE PORT

;-----	SET UP OVERSCAN REGISTER

	INC	DX			; SET OVERSCAN PORT TO A DEFAULT
	MOV	AL,30H			; VALUE 30H FOR ALL MODES EXCEPT 640X200
	OUT	DX,AL			; OUTPUT THE CORRECT VALUE TO 3D9 PORT

;-----	DISPLAY FAILING CHECKPOINT AND

	MOV	AX,CS			; SET STACK SEGMENT TO CODE SEGMENT
	MOV	SS,AX

	MOV	BX,0B000H
	MOV	DS,BX			; SET DS TO B/W DISPLAY BUFFER

Z_0:	MOV	AL,'0'                  ; DISPLAY BANK 000000
	MOV	CX,6
	SUB	DI,DI			; START AT 0
Z:	MOV	[DI],AL 		; WRITE TO DISPLAY REGEN BUFFER
	INC	DI			; POINT TO NEXT POSITION
	INC	DI
	LOOP	Z

	CMP	BH,0B8H 		; CHECK THAT COLOR BUFFER WRITTEN
	JZ	Z_1
	SUB	DI,DI			; POINT TO START OF BUFFER

	MOV	BH,0B0H
	MOV	ES,BX			; ES = MONOCHROME
	MOV	BH,0B8H 		; SET SEGMENT TO COLOR
	MOV	DS,BX			; DS = COLOR
	JMP	Z_0

;-----	PRINT FAILING BIT PATTERN

Z_1:	MOV	AL,' '                  ; DISPLAY A BLANK
	MOV	[DI], AL		; WRITE TO COLOR BUFFER
	MOV	ES:[DI],AL		; WRITE TO MONOCHROME REGEN BUFFER
	INC	DI			; POINT TO NEXT POSITION
	INC	DI
	IN	AL,MFG_PORT+1		; GET THE HIGH BYTE OF FAILING PATTERN
	MOV	CL,4			; SHIFT COUNT
	SHR	AL,CL			; NIBBLE SWAP
	MOV	SP,OFFSET Z1_0
	JMP	SHORT PR

Z1:	IN	AL,MFG_PORT+1
	AND	AL,0FH			; ISOLATE TO LOW NIBBLE
	MOV	SP,OFFSET Z2_0
	JMP	SHORT PR
Z2:	IN	AL,MFG_PORT+2		; GET THE HIGH BYTE OF FAILING PATTERN
	MOV	CL,4			; SHIFT COUNT
	SHR	AL,CL			; NIBBLE SWAP
	MOV	SP,OFFSET Z3_0
	JMP	SHORT PR
Z3:	IN	AL,MFG_PORT+2
	AND	AL,0FH			; ISOLATE TO LOW NIBBLE
	MOV	SP,OFFSET Z4_0		; RETURN TO Z4:

; ----- CONVERT AND PRINT
					; CONVERT 00-0F TO ASCII CHARACTER
PR:	ADD	AL,090H 		; ADD FIRST CONVERSION FACTOR
	DAA				; ADJUST FOR NUMERIC AND ALPHA RANGE
	ADC	AL,040H 		; ADD CONVERSION AND ADJUST LOW NIBBLE
	DAA				; ADJUST HIGH NIBBLE TO ASCII RANGE

	MOV	[DI],AL 		; WRITE TO COLOR BUFFER
	MOV	ES:[DI],AL		; WRITE TO MONOCHROME BUFFER
	INC	DI			; POINT TO NEXT POSITION
	INC	DI
	RET

;-----	DISPLAY 201 ERROR

Z4:	MOV	AL,' '                  ; DISPLAY A BLANK
	MOV	[DI],AL 		; WRITE TO DISPLAY REGEN BUFFER
	MOV	ES:[DI],AL		; WRITE TO MONOCHROME BUFFER
	INC	DI			; POINT TO NEXT POSITION
	INC	DI
	MOV	AL,'2'                  ; DISPLAY 201 ERROR
	MOV	[DI],AL 		; WRITE TO DISPLAY REGEN BUFFER
	MOV	ES:[DI],AL		; WRITE TO MONOCHROME BUFFER
	INC	DI			; POINT TO NEXT POSITION

	INC	DI
	MOV	AL,'0'
	MOV	[DI],AL 		; WRITE TO DISPLAY REGEN BUFFER
	MOV	ES:[DI],AL		; WRITE TO MONOCHROME BUFFER
	INC	DI			; POINT TO NEXT POSITION
	INC	DI
	MOV	AL,'1'
	MOV	[DI],AL 		; WRITE TO DISPLAY REGEN BUFFER
	MOV	ES:[DI],AL		; WRITE TO MONOCHROME BUFFER

;-----	ROLL ERROR CODE IN MFG_PORT --> FIRST THE CHECKPOINT

C31_0:	MOV	AL,0DDH 		;	<><><><><><><><><><><><>
	OUT	MFG_PORT,AL		;	<><> CHECKPOINT  DD <><>
	OUT	MFG_PORT+3,AL		; ALSO DISPLAY CHECK POINT IN PORT 83
	SUB	CX,CX
C31_A:

	SUB	AX,AX			; SETUP SEGMENT
	MOV	DS,AX
	MOV	AX,0AA55H		; WRITE AN AA55
	SUB	DI,DI
	MOV	[DI],AX
	MOV	AX,[DI] 		; READ THE FIRST WORD
	LOOP	C31_A			; DISPLAY CHECKPOINT LONGER
C31_B:
	MOV	[DI],AX
	MOV	AX,[DI]
	LOOP	C31_B
C31_C:
	MOV	[DI],AX
	MOV	AX,[DI]
	LOOP	C31_C
C31_D:
	MOV	[DI],AX
	MOV	AX,[DI]
	LOOP	C31_D
C31_E:
	MOV	[DI],AX
	MOV	AX,[DI]
	LOOP	C31_E

;-----	ROLL ERROR CODE IN MFG_PORT --> NEXT THE HIGH BYTE

	IN	AL,MFG_PORT+1		; XOR OF FAILING BIT PATTERN
	OUT	MFG_PORT,AL		; HIGH BYTE
C31_G:
	MOV	AX,0AA55H		; WRITE AN AA55
	MOV	[DI],AX
	MOV	AX,[DI] 		; READ THE FIRST WORD
	LOOP	C31_G
C31_H:
	MOV	[DI],AX
	MOV	AX,[DI]
	LOOP	C31_H
C31_I:
	MOV	[DI],AX
	MOV	AX,[DI]
	LOOP	C31_I

;-----	ROLL ERROR CODE IN MFG_PORT --> THEN THE LOW BYTE

	IN	AL,MFG_PORT+2		; LOW BYTE
	OUT	MFG_PORT,AL
	MOV	AX,0AA55H		; WRITE AN AA55
C31_K:	SUB	DI,DI
	MOV	[DI],AX
	MOV	AX,[DI] 		; READ THE FIRST WORD
	LOOP	C31_K
C31_L:
	MOV	[DI],AX
	MOV	AX,[DI]
	LOOP	C31_L
C31_M:
	MOV	[DI],AX
	MOV	AX,[DI]
	LOOP	C31_M
C31_N:
	MOV	[DI],AX
	MOV	AX,[DI]
	LOOP	C31_N
	JMP	C31_0			; DO AGAIN

Z1_0	DW	Z1			; TEMPORARY STACK
Z2_0	DW	Z2			; TEMPORARY STACK
Z3_0	DW	Z3			; TEMPORARY STACK
Z4_0	DW	Z4			; TEMPORARY STACK


;-----	CLEAR STORAGE ENTRY


CLR_STG:
	ASSUME	DS:DATA
	REP	STOSW			; STORE 32K WORDS OF 0000
	MOV	AX,DATA 		; RESTORE DATA SEGMENT
	MOV	DS,AX
	MOV	@RESET_FLAG,BX		; RESTORE RESET FLAG

;-----	SETUP STACK SEGMENT AND SP

C33:
	MOV	AX,DATA 		; SET DATA SEGMENT
	MOV	DS,AX
	MOV	SP,POST_SS		; GET STACK VALUE
	MOV	SS,SP			; SET THE STACK UP
	MOV	SP,POST_SP		; STACK IS READY TO GO

;-----	INITIALIZE DISPLAY ROW COUNT

	MOV	@ROWS,25-1		; SET ROWS FOR PRINT SCREEN DEFAULT

	MOV	AL,11H			;	<><><><><><><><><><><><>
	OUT	MFG_PORT,AL		;	<><> CHECKPOINT  11 <><>

;-----	VERIFY SPEED/REFRESH CLOCK RATES  ( ERROR = 1 LONG AND 1 SHORT BEEP )

	XOR	BL,BL			; CLEAR REFRESH CYCLE REPEAT COUNT
	XOR	CX,CX			; INITIALIZE SPEED RATE REGISTER
	EVEN				; PLACE ON EVEN WORD BOUNDARY
C34:
	IN	AL,PORT_B		; READ REFRESH BIT REGISTER
	TEST	AL,REFRESH_BIT		; MASK FOR BIT
	LOOPZ	C34			; DECREMENT LOOP COUNTER TILL ON
C35:
	IN	AL,PORT_B		; READ REFRESH BIT REGISTER
	TEST	AL,REFRESH_BIT		; MASK FOR BIT
	LOOPNZ	C35			; DECREMENT LOOP COUNTER TILL OFF

	DEC	BL			; DECREMENT REFRESH CYCLE REPEAT COUNT
	JNZ	C34			; REPEAT TILL CYCLE COUNT DONE

	CMP	CX,RATE_UPPER		; CHECK FOR RATE BELOW UPPER LIMIT
	JAE	C36			; SKIP ERROR BEEP IF BELOW MAXIMUM
C36E:
	MOV	DX,0101H		; GET BEEP COUNTS FOR REFRESH ERROR
	CALL	ERR_BEEP		; CALL TO POST ERROR BEEP ROUTINES
	HLT				; HALT SYSTEM - BAD REFRESH RATE
C36:
	CMP	CX,RATE_LOWER		; CHECK FOR RATE ABOVE LOWER LIMIT
	JA	C36E			; GO TO ERROR BEEP IF BELOW MINIMUM

;-----	GET THE INPUT BUFFER (SWITCH SETTINGS)

	IN	AL,DMA_PAGE+1		; GET THE SWITCH SETTINGS
	AND	AL,KEY_BD_INHIB+DSP_JMP+MFG_LOOP+BASE_MEM+BASE_MEM8 ; STRIP BITS
	MOV	@MFG_TST,AL		; SAVE SETTINGS
	SUB	AL,AL			; RESET DMA_PAGE
	OUT	DMA_PAGE+1,AL

;----------------------------------------
; TEST.11A				:
;	VERIFY 286 LGDT/SGDT LIDT/SIDT	:
;	INSTRUCTIONS			:
; DESCRIPTION				:
;	LOAD GDT AND IDT REGISTERS WITH :
;	AA,55,00 AND VERIFY CORRECT.	:
;----------------------------------------

;-----	VERIFY STATUS INDICATE COMPATIBILITY (REAL) MODE

	SMSW	AX			; GET THE CURRENT STATUS WORD
	TEST	AX,0FH			; PE/MP/EM/TS BITS SHOULD BE ZERO
	JNZ	ERR_PROT		; GO IF STATUS NOT REAL MODE

;-----	TEST PROTECTED MODE REGISTERS

	MOV	AL,12H			;	<><><><><><><><><><><><>
	OUT	MFG_PORT,AL		;	<><> CHECKPOINT  12 <><>

	PUSH	DS			; SET ES TO SAME SEGMENT AS DS
	POP	ES
	MOV	DI,SYS_IDT_LOC		; USE THIS AREA TO BUILD TEST PATTERN
	MOV	CX,3
	MOV	AX,0AAAAH		; FIRST PATTERN
	CALL	WRT_PAT
	MOV	AX,05555H
	CALL	WRT_PAT 		; WRITE NEXT PATTERN
	SUB	AX,AX			; WRITE 0
	CALL	WRT_PAT

;-----	TEST 286 CONTROL FLAGS

	STD				; SET DIRECTION FLAG FOR DECREMENT
	PUSHF				; GET THE FLAGS
	POP	AX
	TEST	AX,0200H		; INTERRUPT FLAG SHOULD BE OFF
	JNZ	ERR_PROT		; GO IF NOT
	TEST	AX,0400H		; CHECK DIRECTION FLAG
	JZ	ERR_PROT		; GO IF NOT SET
	CLD				; CLEAR DIRECTION FLAG
	PUSHF				; INSURE DIRECTION FLAG IS RESET
	POP	AX
	TEST	AX,0400H
	JNZ	ERR_PROT		; GO IF NOT

	JMP	SHORT C37A		; TEST OK CONTINUE
ERR_PROT:
	HLT				; PROTECTED MODE REGISTER FAILURE
	JMP	SHORT ERR_PROT		; INSURE NO BREAKOUT OF HALT

;-----	WRITE TO 286 REGISTERS

WRT_PAT:MOV	CX,3
	REP	STOSW			; STORE 6 BYTES OF PATTERN
	MOV	BP,SYS_IDT_LOC
	SEGOV	ES			; LOAD THE IDT
	LIDT	[BP]			; REGISTER FROM THIS AREA
	MOV	BP,SYS_IDT_LOC
	SEGOV	ES			; LOAD THE GDT
	LGDT	[BP]			; FROM THE SAME AREA

;-----	READ AND VERIFY 286 REGISTERS

	MOV	BP,GDT_LOC		; STORE THE REGISTERS HERE
	SEGOV	ES
	SIDT	[BP]			; GET THE IDT REGISTERS
	MOV	BP,GDT_LOC+5
	SEGOV	ES
	SGDT	[BP]			; GET THE GDT REGISTERS
	MOV	DI,SYS_IDT_LOC
	MOV	AX,[DI] 		; GET THE PATTERN WRITTEN
	MOV	CX,5			; CHECK ALL REGISTERS
	MOV	SI,GDT_LOC		; POINT TO THE BEGINNING
C37B:	CMP	AX,ES:[SI]
	JNZ	ERR_PROT		; HALT IF ERROR
	INC	SI			; POINT TO NEXT WORD
	INC	SI
	LOOP	C37B			; CONTINUE TILL DONE
	RET


;--------------------------------------------------------
;	INITIALIZE THE 8259 INTERRUPT #1 CONTROLLER CHIP :
;--------------------------------------------------------
C37A:
	SUB	AL,AL			; RESET MATH PROCESSOR
	OUT	X287+1,AL
	MOV	AL,11H			; ICW1 - EDGE, MASTER, ICW4
	OUT	INTA00,AL
	JMP	$+2			; I/O DELAY
	MOV	AL,8			; SETUP ICW2 INTERRUPT TYPE 8 (8-F)
	OUT	INTA01,AL
	JMP	$+2			; I/O DELAY

	MOV	AL,04H			; SETUP ICW3 MASTER LEVEL 2
	OUT	INTA01,AL
	JMP	$+2			; I/O DELAY
	MOV	AL,01H			; SETUP ICW4 MASTER,8086 MODE
	OUT	INTA01,AL
	JMP	$+2			; I/O DELAY
	MOV	AL,0FFH 		; MASK ALL INTERRUPTS OFF
	OUT	INTA01,AL		; (VIDEO ROUTINE ENABLES INTERRUPTS)

;---------------------------------------------------------
;	INITIALIZE THE 8259 INTERRUPT #2 CONTROLLER CHIP  :
;---------------------------------------------------------

	MOV	AL,13H			;	<><><><><><><><><><><><>
	OUT	MFG_PORT,AL		;	<><> CHECKPOINT  13 <><>

	MOV	AL,11H			; ICW1 - EDGE, SLAVE ICW4
	OUT	INTB00,AL
	JMP	$+2			; I/O DELAY
	MOV	AL,INT_TYPE		; SETUP ICW2 - INTERRUPT TYPE 70 (70-7F)
	OUT	INTB01,AL
	MOV	AL,02H			; SETUP ICW3 - SLAVE LEVEL 2
	JMP	$+2
	OUT	INTB01,AL
	JMP	$+2			; I/O DELAY
	MOV	AL,01H			; SETUP ICW4 - 8086 MODE, SLAVE
	OUT	INTB01,AL
	JMP	$+2			; I/O DELAY
	MOV	AL,0FFH 		; MASK ALL INTERRUPTS OFF
	OUT	INTB01,AL

;-----	SET UP THE INTERRUPT VECTORS TO TEMPORARY INTERRUPT

	MOV	AL,14H			;	<><><><><><><><><><><><>
	OUT	MFG_PORT,AL		;	<><> CHECKPOINT  14 <><>

	MOV	CX,78H			; FILL ALL INTERRUPT LOCATIONS
	SUB	DI,DI			; FIRST INTERRUPT LOCATION
	MOV	ES,DI			; SET (ES) ALSO
D3:	MOV	AX,OFFSET D11		; GET ADDRESS OF INTERRUPT OFFSET
	STOSW				; PLACE IN INTERRUPT VECTOR LOCATION
	MOV	AX,CS			; GET THE CURRENT CODE SEGMENT
	STOSW				; PLACE CODE SEGMENT IN VECTOR LOCATION
	LOOP	D3

;-----	ESTABLISH BIOS SUBROUTINE CALL INTERRUPT VECTORS

	MOV	AL,15H			;	<><><><><><><><><><><><>
	OUT	MFG_PORT,AL		;	<><> CHECKPOINT  15 <><>


	MOV	DI,OFFSET @VIDEO_INT	; SET VIDEO INTERRUPT AREA
	PUSH	CS
	POP	DS			; SET UP ADDRESS OF VECTOR TABLE
	MOV	AX,DS			; SET AX=SEGMENT
	MOV	SI,OFFSET VECTOR_TABLE+16  ; START WITH VIDEO ENTRY
	MOV	CX,16

D3A:	MOVSW				; MOVE VECTOR TABLE TO LOW MEMORY
	INC	DI
	INC	DI			; SKIP SEGMENT POINTER
	LOOP	D3A

;----------------------------------------
; TEST.12				:
;	VERIFY CMOS CHECKSUM/BATTERY OK :
; DESCRIPTION				:
;	DETERMINE IF CONFIG RECORD	:
;	CAN BE USED FOR INITIALIZATION. :
;----------------------------------------
	ASSUME	DS:DATA
	CALL	DDS			;SET THE DATA SEGMENT

	MOV	AL,16H			;	<><><><><><><><><><><><>
	OUT	MFG_PORT,AL		;	<><> CHECKPOINT  16 <><>

;-----	IS THE BATTERY LOW THIS POWER UP?

	MOV	AL,CMOS_REG_D+NMI	; CHECK BATTERY CONDITION
	CALL	CMOS_READ		; READ THE BATTERY STATUS
	TEST	AL,10000000B		; IS THE BATTERY LOW?
	JZ	CMOS1A			; ERROR IF YES

	MOV	AL,CMOS_DIAG+NMI	; GET THE OLD STATUS
	CALL	CMOS_READ		; FROM DIAGNOSTIC STATUS BYTE
	TEST	AL,BAD_BAT		; HAS CUSTOMER SETUP BEEN EXECUTED?
	JZ	CMOS1			; GO CHECK CHECKSUM IF YES

	JMP	SHORT CMOS4		; CONTINUE WITHOUT CONFIGURATION

;-----	SET DEFECTIVE BATTERY FLAG

CMOS1A: MOV	AL,17H			;	<><><><><><><><><><><><>
	OUT	MFG_PORT,AL		;	<><> CHECKPOINT  17 <><>

	MOV	AX,X*(CMOS_DIAG+NMI)	; CMOS DIAGNOSTIC STATUS BYTE
	CALL	CMOS_READ		; GET THE CURRENT STATUS
	OR	AL,BAD_BAT		; SET THE DEAD BATTERY FLAG
	XCHG	AL,AH			; SAVE
	CALL	CMOS_WRITE		; OUTPUT THE STATUS
	JMP	SHORT CMOS4		; GO TO MINIMUM CONFIGURATION

;-----	VERIFY CHECKSUM

CMOS1:	MOV	AX,X*(CMOS_DIAG+NMI)	; CLEAR OLD STATUS
	CALL	CMOS_READ		; GET THE CURRENT STATUS
	CMP	@RESET_FLAG,1234H	; IS THIS A SOFT RESET
	JNZ	CMOS1_A 		; GO IF NOT

	AND	AL,W_MEM_SIZE		; CLEAR ALL BUT THE CMOS/POR MEMORY SIZE
	JMP	SHORT CMOS1_B
CMOS1_A:
	SUB	AL,AL			; CLEAR STATUS IF POWER ON RESET
CMOS1_B:
	XCHG	AL,AH			; SAVE THE CURRENT STATUS
	CALL	CMOS_WRITE

	SUB	BX,BX
	SUB	CX,CX
	MOV	CL,CMOS_DISKETTE+NMI	; SET START OF CMOS CHECKSUMED AREA
	MOV	CH,CMOS_CKSUM_HI+NMI	; SET END OF CMOS CHECKSUMED AREA +1
					; (FIRST BYTE OF CHECKSUM)
CMOS2:	MOV	AL,CL
	CALL	CMOS_READ		; ADDRESS THE BEGINNING
	SUB	AH,AH			; INSURE AH=0
	ADD	BX,AX			; ADD TO CURRENT VALUE
	INC	CL			; POINT TO NEXT BYTE ADDRESS IN CMOS
	CMP	CH,CL			; FINISHED?  (AT CHECKSUM BYTE HIGH)
	JNZ	CMOS2			; GO IF NOT
	OR	BX,BX			; BX MUST NOT BE 0
	JZ	CMOS3			; CMOS BAD IF CHECKSUM=0
	MOV	AL,CMOS_CKSUM_HI+NMI	; GET THE CHECK SUM HIGH BYTE
	CALL	CMOS_READ		; FIRST BYTE OF CHECKSUM
	MOV	AH,AL			; SAVE IT
	MOV	AL,CMOS_CKSUM_LO+NMI	; SECOND BYTE OF CHECKSUM
	CALL	CMOS_READ
	CMP	AX,BX			; IS THE CHECKSUM OK
	JZ	CMOS4			; GO IF YES

;-----	SET CMOS CHECKSUM ERROR

CMOS3:	MOV	AX,X*(CMOS_DIAG+NMI)	; ADDRESS DIAGNOSTIC STATUS
	CALL	CMOS_READ		; GET THE CURRENT STATUS
	OR	AL,BAD_CKSUM		; SET BAD CHECKSUM FLAG
	XCHG	AL,AH			; SAVE IT
	CALL	CMOS_WRITE		; SET FLAG

;----	INSURE CMOS DIVIDERS SET

CMOS4:
	MOV	AX,X*(CMOS_REG_A+NMI)	; ADDRESS CMOS REGISTER A
	CALL	CMOS_READ		; GET CURRENT DIVISORS
	AND	AL,00FH 		; LOOK AT PERIODIC RATE BITS
	JNZ	CMOS9			; EXIT IF SET TO SOMETHING USEFUL

	MOV	AL,26H			; ELSE SET THE STANDARD DEFAULT USED BY
	XCHG	AL,AH			;  BIOS FOR THE 976.56 US RATE
	CALL	CMOS_WRITE		;  FOR THE PERIODIC CLOCK
CMOS9:
	MOV	AL,18H			;	<><><><><><><><><><><><>
	OUT	MFG_PORT,AL		;	<><> CHECKPOINT  18 <><>

;-----	ENABLE PROTECTED MODE

	IN	AL,PORT_B		; DISABLE MEMORY AND I/O PARITY CHECKS
	OR	AL,RAM_PAR_OFF
	OUT	PORT_B,AL

;-----	SET RETURN ADDRESS BYTE IN CMOS

	MOV	AL,19H			;	<><><><><><><><><><><><>
	OUT	MFG_PORT,AL		;	<><> CHECKPOINT  19 <><>

	MOV	AX,1*H+(CMOS_SHUT_DOWN+NMI)   ; SET THE RETURN ADDRESS FOR
	CALL	CMOS_WRITE		; THE FIRST SHUTDOWN RETURN ADDRESS

	MOV	SP,POST_SS		; SET STACK FOR SYSINIT1
	MOV	SS,SP
	MOV	SP,POST_SP
	CALL	SYSINIT1		; CALL THE DESCRIPTOR TABLE BUILDER
					; AND REAL-TO-PROTECTED MODE SWITCHER

	MOV	AL,1AH			;	<><><><><><><><><><><><>
	OUT	MFG_PORT,AL		;	<><> CHECKPOINT  1A <><>

;-----	SET TEMPORARY STACK

	PUSH	BYTE PTR GDT_PTR	; SET (DS:) SELECTOR TO GDT SEGMENT
	POP	DS
	MOV	DS:SS_TEMP.BASE_LO_WORD,0
	MOV	BYTE PTR DS:(SS_TEMP.BASE_HI_BYTE),0
	MOV	SI,SS_TEMP
	MOV	SS,SI
	MOV	SP,MAX_SEG_LEN-2

;-------------------------------------------------------------------------------
; TEST.13								       :
;  PROTECTED MODE TEST AND MEMORY SIZE DETERMINE ( 0 --> 640K ) 	       :
;									       :
; DESCRIPTION:								       :
;     THIS ROUTINE RUNS IN PROTECTED MODE IN ORDER TO ADDRESS ALL OF STORAGE.  :
;     IT CHECKS THE MACHINE STATUS WORD (MSW) FOR PROTECTED MODE AND THE BASE  :
;     MEMORY SIZE IS DETERMINED AND SAVED.  BIT 4 OF THE CMOS DIAGNOSTIC       :
;     STATUS BYTE IS SET IF 512K --> 640K MEMORY IS INSTALLED.		       :
;     DURING A POWER UP SEQUENCE THE MEMORY SIZE DETERMINE IS DONE WITH        :
;     PLANAR AND I/O PARITY CHECKS DISABLED.  DURING A SOFT RESET THE MEMORY   :
;     SIZE DETERMINE WILL CHECK FOR PARITY ERRORS.			       :
;-------------------------------------------------------------------------------

;-----	INSURE PROTECTED MODE

	SMSW	AX			; GET THE MACHINE STATUS WORD
	TEST	AX,VIRTUAL_ENABLE	; ARE WE IN PROTECTED MODE
	JNZ	VIR_OK

SHUT_8: MOV	AX,8*H+(CMOS_SHUT_DOWN+NMI)	; SET THE RETURN ADDRESS
	CALL	CMOS_WRITE		; AND SET SHUTDOWN 8
	JMP	PROC_SHUTDOWN		; CAUSE A SHUTDOWN

;-----	VIRTUAL MODE ERROR HALT

SHUT8:	HLT
	JMP	SHUT8			; ERROR HALT

;-----	64K SEGMENT LIMIT

VIR_OK: MOV	DS:ES_TEMP.SEG_LIMIT,MAX_SEG_LEN

;-----	CPL0, DATA ACCESS RIGHTS

	MOV	BYTE PTR DS:(ES_TEMP.DATA_ACC_RIGHTS),CPL0_DATA_ACCESS

;-----	START WITH SEGMENT ADDRESS 01-0000 (SECOND 64K)

	MOV	BYTE PTR DS:(ES_TEMP.BASE_HI_BYTE),01H
	MOV	DS:ES_TEMP.BASE_LO_WORD,0H

	MOV	AL,1BH			;	<><><><><><><><><><><><>
	OUT	MFG_PORT,AL		;	<><> CHECKPOINT  1B <><>

	MOV	BX,16*4 		; SET THE FIRST 64K DONE

;-----	START STORAGE SIZE/CLEAR

NOT_DONE:
	PUSH	BYTE PTR ES_TEMP	; POINT ES TO DATA
	POP	ES			; POINT TO SEGMENT TO TEST
	CALL	HOW_BIG 		; DO THE FIRST 64K
	JZ	NOT_FIN 		; CHECK IF TOP OF MEMORY
	JMP	DONE

NOT_FIN:
	ADD	BX,16*4 		; BUMP MEMORY COUNT BY 64K

;-----	DO NEXT 64K (0X0000) BLOCK

	INC	BYTE PTR DS:(ES_TEMP.BASE_HI_BYTE)

;-----	CHECK FOR END OF FIRST 640K (END OF BASE MEMORY)

	CMP	BYTE PTR DS:(ES_TEMP.BASE_HI_BYTE),0AH
	JNZ	NOT_DONE		; GO IF NOT
	CALL	HOW_BIG_END		; GO SET MEMORY SIZE
	JMP	DONE

;-----	FILL/CHECK LOOP

HOW_BIG:
	SUB	DI,DI
	MOV	AX,0AA55H		; TEST PATTERN
	MOV	CX,AX			; SAVE PATTERN
	MOV	ES:[DI],AX		; WRITE PATTERN TO MEMORY
	MOV	AL,0FH			; PUT SOMETHING IN AL
	MOV	AX,ES:[DI]		; GET PATTERN
	MOV	ES:[DI],AX		; INSURE NO PARITY I/O CHECK
	XOR	AX,CX			; COMPARE PATTERNS
	JNZ	HOW_BIG_END		; GO END IF NO COMPARE

	PUSH	DS
	PUSH	BYTE PTR RSDA_PTR	; POINT TO SYSTEM DATA AREA
	POP	DS			; GET (DS:)

;-----	IS THIS A SOFT RESET

	CMP	@RESET_FLAG,1234H	; SOFT RESET
	POP	DS			; RESTORE DS
	JNZ	HOW_BIG_2		; GO IF NOT SOFT RESET

;-----	INSURE NO PARITY WITH PARITY BITS OFF

	MOV	WORD PTR ES:[DI],0101H	; TURN OFF BOTH PARITY BITS

	IN	AL,PORT_B
	OR	AL,RAM_PAR_OFF		; TOGGLE PARITY CHECK ENABLES
	OUT	PORT_B,AL
	AND	AL,RAM_PAR_ON
	OUT	PORT_B,AL
	PUSH	BYTE PTR 0FFH		; PLACE 0FFFFH IN STACK (BUS BITS ON)
	POP	AX			; DELAY - CAUSING BUS BITS ON
	MOV	AX,ES:[DI]		; CHECK PARITY

	IN	AL,PORT_B		; CHECK FOR PLANAR OR I/O PARITY CHECK
	AND	AL,PARITY_ERR
	MOV	ES:[DI],AX		; CLEAR POSSIBLE PARITY ERROR
	JNZ	HOW_BIG_END		; GO IF PLANAR OR I/O PARITY CHECK

;-----	CHECK ALL BITS WRITE OK

	MOV	WORD PTR ES:[DI],0FFFFH 	; TURN ON ALL BITS
	MOV	AX,ES:[DI]		; CHECK FOR FFFFH
	PUSH	AX			; SAVE RESULTS
	IN	AL,PORT_B		; CHECK FOR PLANAR OR I/O PARITY CHECK
	AND	AL,PARITY_ERR
	MOV	ES:[DI],AX		; CLEAR POSSIBLE PARITY ERROR
	POP	AX			; GET RESULTS
	JNZ	HOW_BIG_END		; GO IF PARITY CHECK
	CMP	AX,0FFFFH
	JNZ	HOW_BIG_END

;-----	CHECK 64K BLOCK FOR PARITY CHECK

HOW_BIG_2:
	SUB	AX,AX			; WRITE ZEROS
	MOV	CX,2000H*4		; SET COUNT FOR 32K WORDS
	REP	STOSW			; FILL 32K WORDS

	PUSH	DS
	PUSH	ES
	PUSH	ES			; GET ES TO DS
	POP	DS
	MOV	CX,2000H*4		; SET COUNT FOR 32K WORDS
	SUB	SI,SI
	REP	LODSW
	SUB	DI,DI			; SET TO BEGINNING OF BLOCK
	IN	AL,PORT_B		; CHECK FOR PLANAR OR I/O PARITY CHECK
	AND	AL,PARITY_ERR
	MOV	WORD PTR ES:[DI],0	; CLEAR POSSIBLE PARITY ERROR
	POP	ES			; RESTORE SEGMENTS
	POP	DS
	JNZ	HOW_BIG_END		; GO IF PLANAR OR I/O PARITY CHECK

	RET

HOW_BIG_END:
	PUSHF				; SAVE THE CURRENT FLAGS
	MOV	AL,1CH			;	<><><><><><><><><><><><>
	OUT	MFG_PORT,AL		;	<><> CHECKPOINT  1C <><>

;-----	SET OR RESET 512 TO 640 INSTALLED FLAG

	MOV	AX,X*(CMOS_INFO128+NMI) ; SET/RESET 640K STATUS FLAG
	CALL	CMOS_READ		; GET THE DIAGNOSTIC STATUS
	OR	AL,M640K
	CMP	BX,512			; CHECK MEMORY SIZE
	JA	K640			; SET FLAG FOR 512 - 640 INSTALLED
	AND	AL,NOT M640K
K640:
	XCHG	AL,AH			; SAVE THE SUTUS
	CALL	CMOS_WRITE		; RESTORE THE STATUS

	PUSH	BYTE PTR RSDA_PTR	; RESTORE THE DATA SEGMENT
	POP	DS
	MOV	@MEMORY_SIZE,BX 	; SAVE MEMORY SIZE
	POPF				; RESTORE THE FLAG REGISTER
	RET

;-------------------------------------------------------------------------------
; TEST.13A								       :
;  PROTECTED MODE TEST AND MEMORY SIZE DETERMINE  ( ABOVE 1024K )	       :
;									       :
; DESCRIPTION:								       :
;     THIS ROUTINE RUNS IN PROTECTED MODE IN ORDER TO ADDRESS ABOVE 1 MEG.     :
;     THE MEMORY SIZE IS DETERMINED AND SAVED IN CMOS.			       :
;     DURING A POWER UP SEQUENCE THE MEMORY SIZE DETERMINE IS DONE WITH        :
;     PLANAR AND I/O PARITY CHECKS DISABLED.  DURING A SOFT RESET THE MEMORY   :
;     SIZE DETERMINE WILL CHECK FOR PARITY ERRORS.			       :
;-------------------------------------------------------------------------------

DONE:
	PUSH	BYTE PTR GDT_PTR	; POINT DS TO THE DESCRIPTOR TABLE
	POP	DS

;-----	START WITH SEGMENT ADDRESS 10-0000 (ONE MEG AND ABOVE)

	MOV	BYTE PTR DS:(ES_TEMP.BASE_HI_BYTE),10H
	MOV	DS:ES_TEMP.BASE_LO_WORD,0H

	MOV	AL,1DH			;	<><><><><><><><><><><><>
	OUT	MFG_PORT,AL		;	<><> CHECKPOINT  1D <><>

	SUB	BX,BX			; START WITH COUNT 0

;-----	START STORAGE SIZE/CLEAR

NOT_DONE1:
	PUSH	BYTE PTR ES_TEMP	; POINT ES TO DATA
	POP	ES			; POINT TO SEGMENT TO TEST
	CALL	HOW_BIG1		; DO THE FIRST 64K
	JZ	DONEA			; CHECK IF TOP

	JMP	DONE1			; GO IF TOP

DONEA:	ADD	BX,16*4 		; BUMP MEMORY COUNT BY 64K

;-----	DO NEXT 64K (XX0000) BLOCK

	INC	BYTE PTR DS:(ES_TEMP.BASE_HI_BYTE)

;-----	CHECK FOR TOP OF MEMORY (FE0000)

	CMP	BYTE PTR DS:(ES_TEMP.BASE_HI_BYTE),0FEH ; LAST OF MEMORY?
	JNZ	NOT_DONE1				; GO IF NOT
	CALL	HOW_BIG_END1				; GO SET MEMORY SIZE
	JMP	DONE1

;-----	FILL/CHECK LOOP

HOW_BIG1:
	SUB	DI,DI
	MOV	AX,0AA55H		; TEST PATTERN
	MOV	CX,AX			; SAVE PATTERN
	MOV	ES:[DI],AX		; SEND PATTERN TO MEMORY
	MOV	AL,0FH			; PUT SOMETHING IN AL
	MOV	AX,ES:[DI]		; GET PATTERN
	MOV	ES:[DI],AX		; INSURE NO PARITY I/O CHECK
	XOR	AX,CX			; COMPARE PATTERNS
	JNZ	HOW_BIG_END1		; GO END IF NO COMPARE

;-----	IS THIS A SOFT RESET

	PUSH	DS
	PUSH	BYTE PTR RSDA_PTR	; POINT TO SYSTEM DATA AREA
	POP	DS
	CMP	@RESET_FLAG,1234H	; SOFT RESET
	POP	DS			; RESTORE DS
	JNZ	HOW_BIG_2A		; GO IF NOT SOFT RESET

;-----	CHECK PARITY WITH PARITY BITS OFF

	MOV	WORD PTR ES:[DI],0101H	; TURN OFF BOTH PARITY BITS
	PUSH	BYTE PTR 0FFH		; PLACE 0FFFFH IN STACK (BUS BITS ON)
	POP	AX			; DELAY - CAUSING BUS BITS ON
	MOV	AX,ES:[DI]		; CHECK PARITY

	IN	AL,PORT_B		; CHECK FOR PLANAR OR I/O PARITY CHECK
	AND	AL,PARITY_ERR
	MOV	ES:[DI],AX		; CLEAR POSSIBLE PARITY ERROR
	JNZ	HOW_BIG_END1		; GO IF PLANAR OR I/O PARITY CHECK

;-----	CHECK ALL BITS

	MOV	WORD PTR ES:[DI],0FFFFH ; TURN ON ALL BITS
	PUSH	BYTE PTR 0		; PLACE 00000H IN STACK (BUS BITS OFF)
	POP	AX			; DELAY - CAUSING BUS BITS OFF
	MOV	AX,ES:[DI]		; CHECK FOR FFPFH
	PUSH	AX			; SAVE RESULTS
	IN	AL,PORT_B		; CHECK FOR PLANAR OR I/O PARITY CHECK
	AND	AL,PARITY_ERR
	MOV	ES:[DI],AX		; CLEAR POSSIBLE PARITY ERROR
	POP	AX			; GET RESULTS
	JNZ	HOW_BIG_END1		; GO IF PLANAR OR I/O PARITY CHECK
	CMP	AX,0FFFFH
	JNZ	HOW_BIG_END1

;-----	CLEAR 64K BLOCK OF MEMORY

HOW_BIG_2A:
	SUB	AX,AX			; WRITE ZEROS
	MOV	CX,2000H*4		; SET COUNT FOR 32K WORDS
	REP	STOSW			; FILL 32K WORDS

;-----	CHECK 64K BLOCK FOR PARITY CHECK (VALID TEST DURING SOFT RESET ONLY)

	PUSH	DS
	PUSH	ES
	PUSH	ES			; GET ES TO DS
	POP	DS
	MOV	CX,2000H*4		; SET COUNT FOR 32K WORDS
	SUB	SI,SI
	REP	LODSW
	SUB	DI,DI			; SET TO BEGINNING OF BLOCK
	IN	AL,PORT_B		; CHECK FOR PLANAR OR I/O PARITY CHECK
	AND	AL,PARITY_ERR
	MOV	WORD PTR ES:[DI],0	; CLEAR POSSIBLE PARITY ERROR
	POP	ES			; RESTORE SEGMENT
	POP	DS
	JNZ	HOW_BIG_END1		; GO IF PLANAR OR I/O PARITY CHECK

	RET

HOW_BIG_END1:
	MOV	AL,1EH			;	<><><><><><><><><><><><>
	OUT	MFG_PORT,AL		;	<><> CHECKPOINT  1E <><>

;-----	SET EXPANSION MEMORY SIZE DETERMINED IN CMOS

	MOV	AL,CMOS_U_M_S_LO+NMI	; ADDRESS LOW BYTE
	MOV	AH,BL			; GET LOW MEMORY SIZE
	CALL	CMOS_WRITE		; SET LOW BYTE
	MOV	AL,CMOS_U_M_S_HI+NMI	; ADDRESS HI BYTE
	MOV	AH,BH			; GET THE HIGH MEMORY SIZE
	CALL	CMOS_WRITE		; PLACE IN CMOS
	RET

;-----	TEST ADDRESS LINES 19 - 23

DONE1:	MOV	AL,1FH			;	<><><><><><><><><><><><>
	OUT	MFG_PORT,AL		;	<><> CHECKPOINT  1F <><>
	MOV	BYTE PTR DS:(ES_TEMP.BASE_HI_BYTE),00H
	SUB	DI,DI			; SET LOCATION POINTER TO ZERO
	MOV	DX,0FFFFH		; WRITE FFFF AT ADDRESS 0
	CALL	SD0
	SUB	DX,DX			; WRITE 0

	MOV	BYTE PTR DS:(ES_TEMP.BASE_HI_BYTE),08H
	CALL	SD0
	MOV	BYTE PTR DS:(ES_TEMP.BASE_HI_BYTE),10H
	CALL	SD0
	MOV	BYTE PTR DS:(ES_TEMP.BASE_HI_BYTE),20H
	CALL	SD0
	MOV	BYTE PTR DS:(ES_TEMP.BASE_HI_BYTE),40H
	CALL	SD0
	MOV	BYTE PTR DS:(ES_TEMP.BASE_HI_BYTE),80H
	CALL	SD0

	JMP	SHORT SD2		; TEST PASSED CONTINUE

SD0:
	PUSH	BYTE PTR ES_TEMP	; POINT ES TO DATA
	POP	ES			; POINT TO SEGMENT TO TEST
	MOV	ES:[DI],DX		; WRITE THE PATTERN

	MOV	BYTE PTR DS:(ES_TEMP.BASE_HI_BYTE),00H

	PUSH	BYTE PTR ES_TEMP	; POINT ES TO DATA
	POP	ES			; POINT TO SEGMENT TO TEST
	CMP	WORD PTR ES:[DI],0FFFFH ; DID LOCATION 0 CHANGE?
	JZ	SD1			; CONTINUE IF NOT
	JMP	SHUT_8			; GO HALT IF YES
SD1:
	RET

;-----	CAUSE A SHUTDOWN

SD2:	MOV	AL,20H			;	<><><><><><><><><><><><>
	OUT	MFG_PORT,AL		;	<><> CHECKPOINT  20 <><>
	IN	AL,PORT_B
	OR	AL,RAM_PAR_OFF		; TOGGLE PARITY CHECK ENABLES
	OUT	PORT_B,AL
	AND	AL,RAM_PAR_ON
	OUT	PORT_B,AL
	JMP	PROC_SHUTDOWN		; CAUSE A SHUTDOWN (RETURN VIA JUMP)

;----------------------------------------
;	RETURN 1 FROM SHUTDOWN		:
;----------------------------------------

SHUT1:	MOV	AL,21H			;	<><><><><><><><><><><><>
	OUT	MFG_PORT,AL		;	<><> CHECKPOINT  21 <><>
	MOV	SP,ABS0 		; SET REAL MODE STACK
	MOV	SS,SP
	MOV	SP,OFFSET @TOS

;-----	SET DIVIDE 0 VECTOR OFFSET

	SUB	DI,DI			; POINT TO FIRST INTERRUPT LOCATION
	MOV	ES,DI			; SET ES TO ABS0 SEGMENT
	MOV	AX,OFFSET D11		; GET ADDRESS OF INTERRUPT OFFSET
	STOSW				; PLACE OFFSET IF NULL HANDLER IN VECTOR

	CALL	DDS			; SET UP THE REAL DATA AREA

;-----	GET THE CONFIGURATION FROM CMOS

	MOV	AX,X*(CMOS_DIAG+NMI)	; CHECK CMOS GOOD
	CALL	CMOS_READ		; GET THE STATUS
	TEST	AL,BAD_BAT+BAD_CKSUM	; VALID CMOS ?
	JZ	M_OK			; GO IF YES
	JMP	BAD_MOS 		; GO IF NOT
M_OK:
	AND	AL,0DFH 		; CLEAR THE MINIMUM CONFIG BIT
	XCHG	AL,AH			; SAVE THE STATUS BYTE
	CALL	CMOS_WRITE		; BACK INTO CMOS

;-----	CHECK FOR CMOS RUN IN MODE

	CMP	@RESET_FLAG,1234H	; CHECK FOR SOFT RESET
	JE	M_OK_64 		; BYPASS IF SOFT RESET

	MOV	AL,CMOS_B_M_S_HI+NMI	; GET THE BASE MEMORY SIZE HIGH BYTE
	CALL	CMOS_READ
	AND	AL,0C0H 		; MASK FOR MANUFACTURING TEST BITS
	CMP	AL,0C0H 		; CHECK FOR MANUFACTURING TEST MODE SET
	JNE	M_OK_64 		; SKIP IF NOT MANUFACTURING LINE TEST

	MOV	BYTE PTR @RESET_FLAG,64H; ELSE SET THE MFG TEST FLAG

;----	INSURE CONFIGURATION HAS CORRECT VIDEO TYPE

M_OK_64:
	MOV	AL,CMOS_EQUIP+NMI	; GET THE EQUIPMENT BYTE
	CALL	CMOS_READ
	MOV	AH,AL			; SAVE VIDEO TYPE
	TEST	AL,030H 		; ANY VIDEO?
	JNZ	MOS_OK_1		; CONTINUE
	CALL	CHK_VIDEO		; INSURE VIDEO ROM PRESENT
	JZ	MOS_OK			; CONTINUE

	TEST	@MFG_TST,MFG_LOOP	; EXCEPT IF MFG JUMPER IS INSTALLED
	JZ	NORMAL_CONFIG		; GO IF INSTALLED

	JMP	SHORT BAD_MOS		; GO DEFAULT

;-----	ROUTINE CHECK FOR VIDEO FEATURE ROM PRESENT

CHK_VIDEO:
	MOV	CX,0C000H		; START OF FEATURE I/O ROM
CHK_VIDEO1:
	PUSH	AX			; SAVE THE CONFIGURATION
	PUSH	DS			; SAVE THE DATA SEGMENT
	PUSH	DI			; SAVE COMPARE REGISTER
	MOV	DS,CX			; GET ROM SEGMENT
	MOV	DI,0AA55H		; GET THE PRESENCE SIGNATURE
	SUB	BX,BX			; CLEAR INDEX POINTER
	MOV	AX,[BX] 		; GET THE FIRST 2 LOCATIONS
	CMP	AX,DI			; IS THE VIDEO FEATURE ROM PRESENT?
	POP	DI			; RESTORE WORK REGISTER
	POP	DS			; RESTORE DATA SEGMENT
	POP	AX			; GET THE CONFIGURATION
	JZ	CHK_VIDEO2		; GO IF VIDEO ROM INSTALLED

	ADD	CX,080H 		; POINT TO NEXT 2K BLOCK
	CMP	CX,0C800H		; TOP OF VIDEO ROM AREA YET?
	JL	CHK_VIDEO1		; TRY AGAIN
	AND	CX,CX			; SET NON ZERO FLAG
CHK_VIDEO2:
	RET				; RETURN TO CALLER

;-----	CMOS VIDEO BITS NON ZERO (CHECK FOR PRIMARY DISPLAY AND NO VIDEO ROM)

MOS_OK_1:
	CALL	CHK_VIDEO		; IS THE VIDEO ROM INSTALLED?
	JZ	BAD_MOS 		; WRONG CONFIGURATION IN CONFIG BYTE

	MOV	AL,AH			; RESTORE CONFIGURATION
	TEST	@MFG_TST,DSP_JMP	; CHECK FOR DISPLAY JUMPER
	JZ	MOS_OK_2		; GO IF COLOR CARD IS PRIMARY DISPLAY

;-----	MONOCHROME CARD IS PRIMARY DISPLAY     (NO JUMPER INSTALLED)

	AND	AL,30H			; INSURE MONOCHROME IS PRIMARY
	CMP	AL,30H			; CONFIGURATION OK?
	JNZ	BAD_MOS 		; GO IF NOT
	MOV	AL,AH			; RESTORE CONFIGURATION
	JMP	SHORT MOS_OK		; USE THE CONFIGURATION BYTE FOR DISPLAY

;-----	COLOR CARD

MOS_OK_2:
	AND	AL,30H			; STRIP UNWANTED BITS
	CMP	AL,30H			; MUST NOT BE MONO WITH JUMPER INSTALLED
	MOV	AL,AH			; RESTORE CONFIGURATION
	JZ	BAD_MOS 		; GO IF YES

;-----	CONFIGURATION MUST HAVE AT LEAST ONE DISKETTE

MOS_OK: TEST	AL,01H			; MUST HAVE AT LEAST ONE DISKETTE
	JNZ	NORMAL_CONFIG		; GO SET CONFIGURATION IF OK
	TEST	@MFG_TST,MFG_LOOP	; EXCEPT IF MFG JUMPER IS INSTALLED
	JZ	NORMAL_CONFIG		; GO IF INSTALLED

;-----	MINIMUM CONFIGURATION WITH BAD CMOS OR NON VALID VIDEO

BAD_MOS:
	MOV	AX,CMOS_DIAG+NMI	; GET THE DIAGNOSTIC STATUS
	CALL	CMOS_READ
	TEST	AL,BAD_BAT+BAD_CKSUM	; WAS BATTERY DEFECTIVE OR BAD CHECKSUM
	JNZ	BAD_MOS1		; GO IF YES

	CALL	CONFIG_BAD		; SET THE MINIMUM CONFIGURATION FLAG
BAD_MOS1:
	CALL	CHK_VIDEO		; CHECK FOR VIDEO ROM
	MOV	AL,01H			; DISKETTE ONLY
	JZ	NORMAL_CONFIG		; GO IF VIDEO ROM PRESENT

	TEST	@MFG_TST,DSP_JMP	; CHECK FOR DISPLAY JUMPER
	MOV	AL,11H			; DEFAULT TO 40X25 COLOR
	JZ	NORMAL_CONFIG		; GO IF JUMPER IS INSTALLED

	MOV	AL,31H			; DISKETTE / B/W DISPLAY 80X25

;----------------------------------------
;	CONFIGURATION AND MFG MODE	:
;----------------------------------------

NORMAL_CONFIG:
	TEST	@MFG_TST,MFG_LOOP	; IS THE MANUFACTURING JUMPER INSTALLED
	JNZ	NORM1			; GO IF NOT
	AND	AL,03EH 		; STRIP DISKETTE FOR MFG TEST

NORM1:	SUB	AH,AH
	MOV	@EQUIP_FLAG,AX		; SAVE SWITCH INFORMATION
	CMP	@RESET_FLAG,1234H	; BYPASS IF SOFT RESET
	JZ	E6

;-----	GET THE FIRST SELF TEST RESULTS FROM KEYBOARD

	MOV	AL,WRITE_8042_LOC	; ENABLE KEYBOARD
	CALL	C8042			; ISSUE WRITE BYTE COMMAND
	MOV	AL,4DH			; ENABLE OUTPUT BUFFER FULL INTERRUPT,
					; SET SYSTEM FLAG, PC 1 COMPATIBILITY,
	OUT	PORT_A,AL		; INHIBIT OVERRIDE, ENABLE KEYBOARD

	SUB	CX,CX			; WAIT FOR COMMAND ACCEPTED
	CALL	C42_1

	MOV	CX,07FFFH		; SET LOOP COUNT FOR APPROXIMATELY 100MS
					; TO RESPOND
TST6:	IN	AL,STATUS_PORT		; WAIT FOR OUTPUT BUFFER FULL
	TEST	AL,OUT_BUF_FULL
	LOOPZ	TST6			; TRY AGAIN IF NOT

	PUSHF				; SAVE FLAGS
	MOV	AL,DIS_KBD		; DISABLE KEYBOARD
	CALL	C8042			; ISSUE THE COMMAND
	POPF				; RESTORE FLAGS
	JZ	E6			; CONTINUE WITHOUT RESULTS

	IN	AL,PORT_A		; GET INPUT FROM KEYBOARD
	MOV	BYTE PTR @RESET_FLAG,AL ; TEMPORARY SAVE FOR AA RECEIVED

;-----	CHECK FOR MFG REQUEST

	CMP	AL,065H 		; LOAD MANUFACTURING TEST REQUEST?
	JNE	E6			; CONTINUE IF NOT
	JMP	MFG_BOOT		; ELSE GO TO MANUFACTURING BOOTSTRAP

;--------------------------------------------------------
; TEST.14						:
;	INITIALIZE AND START CRT CONTROLLER (6845)	:
;	TEST VIDEO READ/WRITE STORAGE.			:
; DESCRIPTION						:
;	RESET THE VIDEO ENABLE SIGNAL.			:
;	SELECT ALPHANUMERIC MODE, 40 * 25, B & W.	:
;	READ/WRITE DATA PATTERNS TO MEMORY, CHECK	:
;	STORAGE ADDRESSABILITY. 			:
; ERROR = 1 LONG AND 2 SHORT BEEPS			:
;--------------------------------------------------------

E6:
	MOV	AX,@EQUIP_FLAG		; GET SENSE INFORMATION
	PUSH	AX			; SAVE IT
	MOV	AL,30H			; FORCE MONOCHROME TYPE
	MOV	@EQUIP_FLAG,AX		; INTO EQUIPMENT FLAG
	SUB	AX,AX			; MODE SET COMMAND FOR DEFAULT MODE
	INT	INT_VIDEO		; SEND INITIALIZATION TO B/W CARD
	MOV	AL,20H			; FORCE COLOR AT 80 BY 25
	MOV	@EQUIP_FLAG,AX		; INTO EQUIPMENT FLAG TO CLEAR BUFFERS
	MOV	AX,0003H		; AND INITIALIZATION COLOR CARD 80X25
	INT	INT_VIDEO		; MODE SET 80 X 25
	MOV	AX,0001H		; SET COLOR 40 X 25 MODE
	INT	INT_VIDEO		; SET DEFAULT COLOR MODE
	POP	AX			; RECOVER REAL SWITCH INFORMATION
	MOV	@EQUIP_FLAG,AX		; RESTORE IT
	AND	AL,30H			; ISOLATE VIDEO SWITCHES
	JNZ	E7			; VIDEO SWITCHES SET TO 0?
	PUSH	DS			; SAVE THE DATA SEGMENT
	PUSH	AX
	SUB	AX,AX			; SET DATA SEGMENT TO 0
	MOV	DS,AX
	MOV	DI,OFFSET @VIDEO_INT	; SET INTERRUPT 10H TO DUMMY
	MOV	WORD PTR [DI],OFFSET DUMMY_RETURN  ; RETURN IF NO VIDEO CARD
	POP	AX			; RESTORE REGISTERS
	POP	DS
	JMP	SHORT E18_1		; BYPASS VIDEO TEST
E7:
	CMP	AL,30H			; B/W CARD ATTACHED?
	JE	E8			; YES - SET MODE FOR B/W CARD
	INC	AH			; SET COLOR MODE FOR COLOR CARD
	CMP	AL,20H			; 80X25 MODE SELECTED?
	JNE	E8			; NO - SET MODE FOR 40X25
	MOV	AH,3			; SET MODE FOR 80X25
E8:
	XCHG	AH,AL
	PUSH	AX			; SAVE VIDEO MODE ON STACK
	SUB	AH,AH			; INITIALIZE TO ALPHANUMERIC MD
	INT	INT_VIDEO		; CALL VIDEO_IO
	POP	AX			; RESTORE VIDEO SENSE SWITCHES IN AH
	PUSH	AX			; SAVE VALUE
	MOV	BX,0B000H		; STARTING VIDEO MEMORY ADDRESS B/W CARD
	MOV	DX,3B8H 		; MODE REGISTER FOR B/W
	MOV	CX,2048 		; MEMORY WORD COUNT FOR B/W CARD
	CMP	AH,30H			; B/W VIDEO CARD ATTACHED?
	JE	E9			; YES - GO TEST VIDEO STORAGE
	MOV	BH,0B8H 		; STARTING MEMORY ADDRESS FOR COLOR CARD
	MOV	DX,3D8H 		; MODE REGISTER FOR COLOR CARD
	MOV	CH,20H			; MEMORY WORD COUNT FOR COLOR CARD
E9:
	MOV	AL,@CRT_MODE_SET	; GET CURRENT MODE SET VALUE
	AND	AL,037H 		; SET VIDEO BIT OFF
	OUT	DX,AL			; DISABLE VIDEO FOR COLOR CARD
	MOV	ES,BX			; POINT ES TO VIDEO MEMORY
	MOV	DS,BX			; POINT DS TO VIDEO MEMORY
	ROR	CX,1			; DIVIDE BY 2 FOR WORD COUNT
	CALL	STGTST_CNT		; GO TEST VIDEO READ/WRITE STORAGE
	JNE	E17			; R/W MEMORY FAILURE - BEEP SPEAKER

;------------------------------------------------
; TEST.15					:
;	SETUP VIDEO DATA ON SCREEN FOR VIDEO	:
;	LINE TEST.				:
; DESCRIPTION					:
;	ENABLE VIDEO SIGNAL AND SET MODE.	:
;	DISPLAY A HORIZONTAL BAR ON SCREEN.	:
;------------------------------------------------

	MOV	AL,22H			;	<><><><><><><><><><><><>
	OUT	MFG_PORT,AL		;	<><> CHECKPOINT  22 <><>

	POP	AX			; GET VIDEO SENSE SWITCHES (AH)
	PUSH	AX			; SAVE IT
	MOV	AH,0			; ENABLE VIDEO AND SET MODE
	INT	INT_VIDEO		; VIDEO
	MOV	AX,7020H		; WRITE BLANKS IN REVERSE VIDEO
	SUB	DI,DI			; SETUP STARTING LOCATION
	MOV	CX,40			; NUMBER OF BLANKS TO DISPLAY
	REP	STOSW			; WRITE VIDEO STORAGE

;----------------------------------------
; TEST.16				:
;	CRT INTERFACE LINES TEST	:
; DESCRIPTION				:
;	SENSE ON/OFF TRANSITION OF THE	:
;	VIDEO ENABLE AND HORIZONTAL	:
;	SYNC LINES			:
;----------------------------------------

	POP	AX			; GET VIDEO SENSE SWITCH INFORMATION
	PUSH	AX			; SAVE IT
	CMP	AH,30H			; B/W CARD ATTACHED?
	MOV	DX,03BAH		; SETUP ADDRESS OF B/W STATUS PORT
	JE	E11			; YES - GO TEST LINES
	MOV	DX,03DAH		; COLOR CARD IS ATTACHED
E11:
	MOV	AH,8
E12:
	SUB	CX,CX
E13:
	IN	AL,DX			; READ CRT STATUS PORT
	AND	AL,AH			; CHECK VIDEO/HORIZONTAL LINE
	JNZ	E14			; ITS ON - CHECK IF IT GOES OFF
	LOOP	E13			; LOOP UNTIL ON OR TIMEOUT
	JMP	SHORT E17		; GO PRINT ERROR MESSAGE
E14:
	SUB	CX,CX
E15:
	IN	AL,DX			; READ CRT STATUS PORT
	AND	AL,AH			; CHECK VIDEO/HORIZONTAL LINE
	JZ	E16			; ITS ON - CHECK NEXT LINE
	LOOP	E15			; LOOP IF ON UNTIL IT GOES OFF
	JMP	SHORT E17		; GO ERROR BEEP

;-----	CHECK HORIZONTAL LINE
E16:	MOV	CL,3			; GET NEXT BIT TO CHECK
	SHR	AH,CL
	JNZ	E12			; CONTINUE
E18:
	POP	AX			; GET VIDEO SENSE SWITCHES (AH)
	MOV	AH,0			; SET MODE AND DISPLAY CURSOR
	INT	INT_VIDEO		; CALL VIDEO I/O PROCEDURE

;-----	CHECK FOR THE ADVANCED VIDEO CARD

E18_1:	MOV	DX,0C000H		; SET THE LOW SEGMENT VALUE
E18A:
	MOV	AL,23H			;	<><><><><><><><><><><><>
	OUT	MFG_PORT,AL		;	<><> CHECKPOINT  23 <><>
	MOV	DS,DX
	PUSH	DI			; SAVE WORK REGISTER
	MOV	DI,0AA55H		; PRESENCE SIGNATURE
	SUB	BX,BX			; CLEAR POINTER
	MOV	AX,[BX] 		; GET FIRST 2 LOCATIONS
	CMP	AX,DI			; PRESENT?
	POP	DI			; RECOVER REGISTER
	JNZ	E18B			; NO? GO LOOK FOR OTHER MODULES

	CALL	ROM_CHECK		; GO SCAN MODULE
	JMP	SHORT E18C
E18B:
	ADD	DX,0080H		; POINT TO NEXT 2K BLOCK
E18C:
	CMP	DX,0C800H		; TOP OF VIDEO ROM AREA YET?
	JL	E18A			; GO SCAN FOR ANOTHER MODULE

	MOV	AL,24H			;	<><><><><><><><><><><><>
	OUT	MFG_PORT,AL		;	<><> CHECKPOINT  24 <><>

	JMP	POST2			; GO TO NEXT TEST


;-----	CRT ERROR SET MFG CHECKPOINT AND ERROR BEEP

E17:	CALL	DDS			; POINT TO DATA

;-----	CHECKPOINT 0C = MONOCHROME FAILED

	MOV	@MFG_ERR_FLAG,0CH	; <><> CRT ERROR CHECKPOINT  0C <><>
	CMP	BYTE PTR @RESET_FLAG,064H ; IS THIS A MFG REQUEST?
	JZ	E19			; BY PASS ERROR BEEP IF YES
	TEST	@MFG_TST,MFG_LOOP	; IS THE MFG LOOP JUMPER INSTALLED?
	JZ	E19			; BY PASS ERROR BEEP IF YES
	MOV	DX,102H
	CALL	ERR_BEEP		; GO BEEP SPEAKER
E19:
	PUSH	DS
	MOV	AX,@EQUIP_FLAG		; GET THE CURRENT VIDEO
	AND	AL,30H			; STRIP OTHER BITS
	CMP	AL,30H			; IS IT MONOCHROME ?
	JZ	TRY_COLOR		; GO IF YES

;-----	COLOR FAILED TRY MONOCHROME - CHECKPOINT 0D = COLOR FAILED

	MOV	@MFG_ERR_FLAG,0DH	; <><> CRT ERROR CHECKPOINT 0D <><>

	MOV	DX,3B8H 		; DISABLE B/W
	MOV	AL,1
	OUT	DX,AL			; OUTPUT THE DISABLE
	MOV	BX,0B000H		; CHECK FOR MONOCHROME VIDEO MEMORY
	MOV	DS,BX
	MOV	AX,0AA55H		; WRITE AN AA55
	SUB	BX,BX			; TO THE FIRST LOCATION
	MOV	[BX],AX
	JMP	$+2			; ALLOW BUS TO SETTLE
	MOV	AX,[BX] 		; READ THE FIRST LOCATION
	CMP	AX,0AA55H		; IS THE MONOCHROME VIDEO CARD THERE?
	POP	DS			; RESTORE THE DATA SEGMENT
	JNZ	E17_3			; GO IF NOT
	OR	@EQUIP_FLAG,30H 	; TURN ON MONOCHROME BITS IN EQUIP FLAG
	MOV	AX,@EQUIP_FLAG		; ENABLE VIDEO
	SUB	AH,AH
	INT	INT_VIDEO
	JMP	SHORT E17_1		; CONTINUE

;-----	MONOCHROME FAILED TRY COLOR

TRY_COLOR:
	MOV	AL,01H			; SET MODE COLOR 40X25
	SUB	AH,AH
	INT	INT_VIDEO
	MOV	DX,3D8H 		; DISABLE COLOR
	MOV	AL,0
	OUT	DX,AL			; OUTPUT THE DISABLE
	MOV	BX,0B800H		; CHECK FOR COLOR VIDEO MEMORY
	MOV	DS,BX
	MOV	AX,0AA55H		; WRITE AN AA55
	SUB	BX,BX			; TO THE FIRST LOCATION
	MOV	[BX],AX
	JMP	$+2			; ALLOW BUS TO SETTLE
	MOV	AX,[BX] 		; READ THE FIRST LOCATION
	CMP	AX,0AA55H		; IS THE COLOR VIDEO CARD THERE?
	POP	DS			; RESTORE THE DATA SEGMENT
	JNZ	E17_3			; GO IF NOT
	AND	@EQUIP_FLAG,0FFCFH	; TURN OFF VIDEO BITS
	OR	@EQUIP_FLAG,10H 	; SET COLOR 40X24
	MOV	AL,01H
	SUB	AH,AH
	INT	INT_VIDEO
E17_1:
	POP	AX			; SET NEW VIDEO TYPE ON STACK
	MOV	AX,@EQUIP_FLAG
	AND	AL,30H
	CMP	AL,30H			; IS IT THE B/W?
	SUB	AL,AL
	JZ	E17_2			; GO IF YES

	INC	AL			; INITIALIZE FOR 40X25
E17_2:
	PUSH	AX
E17_4:
	JMP	E18

;-----	BOTH VIDEO CARDS FAILED SET DUMMY RETURN IF RETRACE FAILURE

E17_3:
	PUSH	DS
	SUB	AX,AX			; SET DS SEGMENT TO 0
	MOV	DS,AX
	MOV	DI,OFFSET @VIDEO_INT		  ; SET INTERRUPT 10H TO DUMMY
	MOV	WORD PTR [DI],OFFSET DUMMY_RETURN ; RETURN IF NO VIDEO CARD
	POP	DS
	JMP	E18_1			; BYPASS REST OF VIDEO TEST
PAGE
;-------------------------------------------------------------------------------
; MANUFACTURING BOOT TEST CODE ROUTINE					       :
;	LOAD A BLOCK OF TEST CODE THROUGH THE KEYBOARD PORT FOR MANUFACTURING  :
;	TESTS.								       :
;	THIS ROUTINE WILL LOAD A TEST (MAX LENGTH=FAFFH) THROUGH THE KEYBOARD  :
;	PORT. CODE WILL BE LOADED AT LOCATION 0000:0500.   AFTER LOADING,      :
;	CONTROL WILL BE TRANSFERRED TO LOCATION 0000:0500.    THE STACK WILL   :
;	BE LOCATED AT 0000:0400.  THIS ROUTINE ASSUMES THAT THE FIRST 2 BYTES  :
;	TRANSFERRED CONTAIN THE COUNT OF BYTES TO BE LOADED		       :
;	 (BYTE 1=COUNT LOW, BYTE 2=COUNT HI.)				       :
;-------------------------------------------------------------------------------

;-----	DEGATE ADDRESS LINE 20

MFG_BOOT:
	MOV	AH,DISABLE_BIT20	; DEGATE COMMAND FOR ADDRESS LINE 20
	CALL	GATE_A20		; ISSUE TO KEYBOARD ADAPTER AND CLI

;-----	SETUP HARDWARE INTERRUPT VECTOR TABLE LEVEL 0-7 AND SOFTWARE INTERRUPTS

	PUSH	ABS0			; SET ES SEGMENT REGISTER TO ABS0
	POP	ES
	MOV	CX,24			; GET VECTOR COUNT
	MOV	AX,CS			; GET THE CURRENT CODE SEGMENT VALUE
	MOV	DS,AX			; SETUP DS SEGMENT REGISTER TO
	MOV	SI,OFFSET VECTOR_TABLE	; POINT TO THE ROUTINE ADDRESS TABLE
	MOV	DI,OFFSET @INT_PTR	; SET DESTINATION TO FIRST USED VECTOR
MFG_B1:
	MOVSW				; MOVE ONE ROUTINE OFFSET ADDRESS
	STOSW				; INSERT CODE SEGMENT VALUE
	LOOP	MFG_B1			; MOVE THE NUMBER OF ENTRIES REQUIRED

;-----	SETUP HARDWARE INTERRUPT VECTORS LEVEL 8-15 (VECTORS START AT INT 70 H)

	MOV	CX,08			; GET VECTOR COUNT
	MOV	SI,OFFSET SLAVE_VECTOR_TABLE
	MOV	DI,OFFSET @SLAVE_INT_PTR
MFG_B2:
	MOVSW				; MOVE ONE ROUTINE OFFSET ADDRESS
	STOSW				; INSERT CODE SEGMENT VALUE
	LOOP	MFG_B2

;-----	SET UP OTHER INTERRUPTS AS NECESSARY

	ASSUME	DS:ABS0,ES:ABS0
	PUSH	ES					; ES= ABS0
	POP	DS					; SET DS TO ABS0
	MOV	WORD PTR @NMI_PTR,OFFSET NMI_INT	; NMI INTERRUPT
	MOV	WORD PTR @INT5_PTR,OFFSET PRINT_SCREEN	; PRINT SCREEN
	MOV	WORD PTR @BASIC_PTR+2,0F600H		; CASSETTE BASIC SEGMENT

;-----	ENABLE KEYBOARD PORT

	MOV	AL,60H			; WRITE 8042 MEMORY LOCATION 0
	CALL	C8042			; ISSUE THE COMMAND
	MOV	AL,00001001B		; SET INHIBIT OVERRIDE/ENABLE OBF
	OUT	PORT_A,AL		;   INTERRUPT AND NOT PC COMPATIBLE

	CALL	MFG_B4			; GET COUNT LOW
	MOV	BH,AL			; SAVE IT
	CALL	MFG_B4			; GET COUNT HI
	MOV	CH,AL
	MOV	CL,BH			; CX NOW HAS COUNT
	CLD				; SET DIRECTION FLAG TO INCREMENT
	MOV	DI,OFFSET @MFG_TEST_RTN ; SET TARGET OFFSET (DS=0000)
MFG_B3:
	IN	AL,STATUS_PORT		; GET 8042 STATUS PORT
	TEST	AL,OUT_BUF_FULL 	; KEYBOARD REQUEST PENDING?
	JZ	MFG_B3			; LOOP TILL DATA PRESENT
	IN	AL,PORT_A		; GET DATA
	STOSB				; STORE IT
	OUT	MFG_PORT,AL		; DISPLAY CHARACTER AT MFG PORT
	LOOP	MFG_B3			; LOOP TILL ALL BYTES READ

	JMP	@MFG_TEST_RTN		; FAR JUMP TO CODE THAT WAS JUST LOADED

MFG_B4:
	IN	AL,STATUS_PORT		; CHECK FOR OUTPUT BUFFER FULL
	TEST	AL,OUT_BUF_FULL 	;   HANG HERE IF NO DATA AVAILABLE
	LOOPZ	MFG_B4

	IN	AL,PORT_A		; GET THE COUNT
	RET

POST1	ENDP
CODE	ENDS
	END
